From aa2587ce9ed5dc82f50b238b2b56e06dcaf0943d Mon Sep 17 00:00:00 2001 From: Daniel Visca Date: Tue, 13 Oct 2026 19:04:06 -0400 Subject: [PATCH 01/70] feat(metrics): attach trace exemplars to flushed metric series (#1057) (cherry picked from commit 3cc2d6468d22306897db285bf5fa291a94287e71) --- .sampo/changesets/metrics-trace-exemplars.md | 5 + posthog/metrics_capture.py | 90 +++++++++++++ posthog/test/test_metrics.py | 131 +++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 .sampo/changesets/metrics-trace-exemplars.md diff --git a/.sampo/changesets/metrics-trace-exemplars.md b/.sampo/changesets/metrics-trace-exemplars.md new file mode 100644 index 000000000..9617ba446 --- /dev/null +++ b/.sampo/changesets/metrics-trace-exemplars.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +`client.metrics` now attaches a trace exemplar to each series it flushes. A sample recorded inside a sampled span (a PostHog `start_span` span, or the current OpenTelemetry span) stamps its data point with that span's trace ID, span ID, and value, so metric charts can link to a representative trace. One exemplar per series per flush window; the last sample wins. diff --git a/posthog/metrics_capture.py b/posthog/metrics_capture.py index 6e454842c..781aa89b3 100644 --- a/posthog/metrics_capture.py +++ b/posthog/metrics_capture.py @@ -12,6 +12,11 @@ is attached: every attribute value creates a new series, and per-user series are the canonical metrics-cardinality explosion. +A sample recorded inside a sampled span (a PostHog ``start_span`` span, or the +current OpenTelemetry span) stamps its series with an exemplar: the trace and +span IDs plus the value. One exemplar per series per window, last sample wins, +so a metric point links to one representative trace at no cardinality cost. + Delivery is at-least-once: a request that succeeds server-side but fails client-side (e.g. a read timeout) is retried with the next window, which can double-count that window's deltas. Failed flushes retry with exponential @@ -37,6 +42,8 @@ from posthog.utils import remove_trailing_slash from posthog.version import VERSION +from .tracing._traceparent import TRACE_FLAGS_SAMPLED, parse_traceparent + log = logging.getLogger("posthog") MetricAttributeValue = Union[str, int, float, bool] @@ -74,6 +81,8 @@ _DEFAULT_FLUSH_INTERVAL_SECONDS = 10.0 _DEFAULT_MAX_SERIES_PER_FLUSH = 1000 _SCOPE_NAME = "posthog-python" +# None until the first lookup; False when opentelemetry-api is not installed. +_otel_trace: Any = None def _snapshot_attribute_value(value: Any) -> Any: @@ -135,6 +144,52 @@ def _bucket_index_for(value: float, bounds: list) -> int: return len(bounds) +def _parse_sampled_traceparent(value: Any) -> Optional[tuple[str, str]]: + """The (trace_id, span_id) of a sampled W3C ``traceparent``, or None.""" + context = parse_traceparent(value) + if context is None or context.flags != TRACE_FLAGS_SAMPLED: + return None + return context.trace_id, context.span_id + + +def _otel_trace_module() -> Any: + global _otel_trace + if _otel_trace is None: + try: + from opentelemetry import trace + + _otel_trace = trace + except ImportError: + _otel_trace = False + return _otel_trace + + +def _active_trace_context(client: Any) -> Optional[tuple[str, str]]: + """The sampled span a sample is recorded in: PostHog's own active span first, + then the current OpenTelemetry span. An unsampled span is never exported, so + an exemplar pointing at it would link to a trace that does not exist.""" + try: + get_active_span = getattr(client, "get_active_span", None) + span = get_active_span() if callable(get_active_span) else None + if span is not None: + # A PostHog span is active, so it is the innermost context; an + # unsampled one must not fall through to an outer OTel span. + return _parse_sampled_traceparent(span.traceparent()) + except Exception: + pass + + trace = _otel_trace_module() + if not trace: + return None + try: + span_context = trace.get_current_span().get_span_context() + if not span_context.is_valid or not span_context.trace_flags.sampled: + return None + return f"{span_context.trace_id:032x}", f"{span_context.span_id:016x}" + except Exception: + return None + + def _series_key( metric_type: str, name: str, unit: Optional[str], attributes: Optional[dict] ) -> str: @@ -153,6 +208,24 @@ def _series_key( return "\x00".join((metric_type, name, unit or "", attrs_part)) +def _build_exemplars(exemplar: Optional[dict]) -> dict: + # Spread into the data point, so a point without an exemplar keeps its + # exact pre-exemplar wire shape. OTLP/JSON encodes trace and span IDs as hex. + if exemplar is None: + return {} + return { + "exemplars": [ + { + "filteredAttributes": [], + "timeUnixNano": _ms_to_unix_nano(exemplar["time_ms"]), + "asDouble": exemplar["value"], + "traceId": exemplar["trace_id"], + "spanId": exemplar["span_id"], + } + ] + } + + class _SeriesState: __slots__ = ( "name", @@ -163,6 +236,7 @@ class _SeriesState: "total", "last", "hist", + "exemplar", ) def __init__( @@ -195,6 +269,7 @@ def __init__( self.total: Optional[float] = None self.last: Optional[float] = None self.hist: Optional[dict] = None + self.exemplar: Optional[dict] = None class PostHogMetrics: @@ -412,6 +487,7 @@ def _capture( # series identity too — otherwise two indistinguishable data points emit. attributes = {k: v for k, v in attributes.items() if v is not None} key = _series_key(metric_type, name, unit, attributes) + trace_context = _active_trace_context(self._client) with self._lock: self._reset_after_fork_locked() @@ -446,6 +522,13 @@ def _capture( ) self._fold(state, float(value)) + if trace_context is not None: + state.exemplar = { + "trace_id": trace_context[0], + "span_id": trace_context[1], + "value": float(value), + "time_ms": int(time.time() * 1000), + } self._arm_flush_timer() def _reinit_after_fork(self) -> None: @@ -641,6 +724,9 @@ def _merge_window_back(self, window: dict) -> None: self._series[key] = old continue current.window_start_ms = min(current.window_start_ms, old.window_start_ms) + # The live window's exemplar is newer; the old one only fills a gap. + if current.exemplar is None: + current.exemplar = old.exemplar if current.type == "count": current.total = (current.total or 0.0) + (old.total or 0.0) elif current.type == "histogram" and old.hist: @@ -718,6 +804,7 @@ def _build_metrics(self, window: dict) -> list: attributes = _to_otlp_key_value_list(state.attributes or {}) start_nano = _ms_to_unix_nano(state.window_start_ms) + exemplars = _build_exemplars(state.exemplar) if state.type == "count": metric["sum"]["dataPoints"].append( @@ -726,6 +813,7 @@ def _build_metrics(self, window: dict) -> list: "startTimeUnixNano": start_nano, "timeUnixNano": now_nano, "asDouble": state.total or 0.0, + **exemplars, } ) elif state.type == "gauge": @@ -734,6 +822,7 @@ def _build_metrics(self, window: dict) -> list: "attributes": attributes, "timeUnixNano": now_nano, "asDouble": state.last or 0.0, + **exemplars, } ) elif state.hist is not None: @@ -751,6 +840,7 @@ def _build_metrics(self, window: dict) -> list: "max": state.hist["max"], "bucketCounts": state.hist["bucket_counts"], "explicitBounds": DEFAULT_HISTOGRAM_BOUNDS, + **exemplars, } ) diff --git a/posthog/test/test_metrics.py b/posthog/test/test_metrics.py index 0575c2aa1..e25bb34bf 100644 --- a/posthog/test/test_metrics.py +++ b/posthog/test/test_metrics.py @@ -4,6 +4,8 @@ from unittest import mock import pytest +from opentelemetry import trace +from opentelemetry.trace import NonRecordingSpan, SpanContext, TraceFlags import posthog from posthog.client import Client @@ -25,6 +27,21 @@ def client(): c.metrics.reset() +@pytest.fixture +def traced_client(): + # Tracing on, so start_span returns a recording span with its own span ID + # instead of a pass-through that echoes the parent's traceparent. + with mock.patch( + "posthog.tracing._transport._get_session", return_value=mock_session() + ): + c = Client( + FAKE_API_KEY, host="https://us.example.com", sync_mode=True, traces={} + ) + yield c + c.metrics.reset() + c.shutdown() + + def mock_session(status_code=200): session = mock.Mock() session.post.return_value = mock.Mock(status_code=status_code) @@ -586,6 +603,120 @@ def test_any_value_encoding_matches_js(self, client, value, expected): assert attr["value"] == expected +OTEL_TRACE_ID = "4bf92f3577b34da6a3ce929d0e0e4736" +OTEL_SPAN_ID = "00f067aa0ba902b7" + + +def otel_span(sampled): + return NonRecordingSpan( + SpanContext( + trace_id=int(OTEL_TRACE_ID, 16), + span_id=int(OTEL_SPAN_ID, 16), + is_remote=False, + trace_flags=TraceFlags( + TraceFlags.SAMPLED if sampled else TraceFlags.DEFAULT + ), + ) + ) + + +def data_points_by_type(payload): + points = {} + for metric in metrics_from(payload): + for kind in ("sum", "gauge", "histogram"): + if kind in metric: + points[kind] = metric[kind]["dataPoints"][0] + return points + + +def record_one_of_each(client): + client.metrics.count("c", 1) + client.metrics.count("c", 4) + client.metrics.gauge("g", 7) + client.metrics.histogram("h", 12) + + +class TestMetricsExemplars: + def test_sampled_otel_span_stamps_last_sample_on_every_type(self, client): + with trace.use_span(otel_span(sampled=True)): + record_one_of_each(client) + + payload, _, _ = flush_and_capture(client) + points = data_points_by_type(payload) + + for kind, value in (("sum", 4), ("gauge", 7), ("histogram", 12)): + (exemplar,) = points[kind]["exemplars"] + assert exemplar["traceId"] == OTEL_TRACE_ID + assert exemplar["spanId"] == OTEL_SPAN_ID + assert exemplar["asDouble"] == value + assert exemplar["timeUnixNano"].isdigit() + + def test_active_posthog_span_wins_over_outer_otel_span(self, traced_client): + parent_trace_id, parent_span_id = "a" * 32, "b" * 16 + with trace.use_span(otel_span(sampled=True)): + with traced_client.start_span( + "job", parent=f"00-{parent_trace_id}-{parent_span_id}-01" + ) as span: + traced_client.metrics.count("c", 1) + _, trace_id, span_id, _ = span.traceparent().split("-") + + payload, _, _ = flush_and_capture(traced_client) + (exemplar,) = data_points_by_type(payload)["sum"]["exemplars"] + # The recording span's own ID, in the inbound trace, not the parent's. + assert span_id not in (parent_span_id, OTEL_SPAN_ID) + assert (exemplar["traceId"], exemplar["spanId"]) == (parent_trace_id, span_id) + + def test_innermost_posthog_span_is_the_exemplar(self, traced_client): + with traced_client.start_span("request"): + with traced_client.start_span("db.query") as child: + traced_client.metrics.histogram("h", 3) + _, trace_id, span_id, _ = child.traceparent().split("-") + + payload, _, _ = flush_and_capture(traced_client) + (exemplar,) = data_points_by_type(payload)["histogram"]["exemplars"] + assert (exemplar["traceId"], exemplar["spanId"]) == (trace_id, span_id) + + @pytest.mark.parametrize("context", ["no_span", "unsampled_otel_span"]) + def test_no_exemplar_without_a_sampled_span(self, client, context): + if context == "no_span": + record_one_of_each(client) + else: + with trace.use_span(otel_span(sampled=False)): + record_one_of_each(client) + + payload, _, _ = flush_and_capture(client) + for point in data_points_by_type(payload).values(): + assert "exemplars" not in point + + def test_unsampled_posthog_span_hides_a_sampled_outer_otel_span( + self, traced_client + ): + with trace.use_span(otel_span(sampled=True)): + with traced_client.start_span( + "job", parent=f"00-{'a' * 32}-{'b' * 16}-00" + ) as span: + assert span.traceparent().endswith("-00") + record_one_of_each(traced_client) + + payload, _, _ = flush_and_capture(traced_client) + for point in data_points_by_type(payload).values(): + assert "exemplars" not in point + + def test_failed_flush_keeps_exemplar_for_the_retry(self, client): + with trace.use_span(otel_span(sampled=True)): + client.metrics.count("c", 1) + with mock.patch( + "posthog.metrics_capture._get_session", return_value=mock_session(503) + ): + client.metrics.flush() + client.metrics.count("c", 2) + + payload, _, _ = flush_and_capture(client) + point = data_points_by_type(payload)["sum"] + assert point["asDouble"] == 3 + assert point["exemplars"][0]["traceId"] == OTEL_TRACE_ID + + class TestMetricsFailureHandling: def test_fork_drops_inherited_window_and_rearms(self, client): # A forked child inherits a dead timer thread and the parent's window; without the From e61c921e9df940059c0603b9d1a650bd75a194f9 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:14:21 +0000 Subject: [PATCH 02/70] chore: Release v7.69.0 [skip ci] (cherry picked from commit 653ff87684d7453ee01dd3f2f19dbf709bcf6592) --- .sampo/changesets/metrics-trace-exemplars.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/metrics-trace-exemplars.md diff --git a/.sampo/changesets/metrics-trace-exemplars.md b/.sampo/changesets/metrics-trace-exemplars.md deleted file mode 100644 index 9617ba446..000000000 --- a/.sampo/changesets/metrics-trace-exemplars.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -`client.metrics` now attaches a trace exemplar to each series it flushes. A sample recorded inside a sampled span (a PostHog `start_span` span, or the current OpenTelemetry span) stamps its data point with that span's trace ID, span ID, and value, so metric charts can link to a representative trace. One exemplar per series per flush window; the last sample wins. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 1f1a08ffb..a187f190f 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.103 — 2026-10-13 + +### Patch changes + +- Updated dependencies: posthog@7.69.0 + ## 0.1.102 — 2026-10-12 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 3f86be56b..f1710339d 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.102" +version = "0.1.103" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 64968df2d..424723c31 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.69.0 — 2026-10-13 + +### Minor changes + +- [3cc2d64](https://github.com/posthog/posthog-python/commit/3cc2d6468d22306897db285bf5fa291a94287e71) `client.metrics` now attaches a trace exemplar to each series it flushes. A sample recorded inside a sampled span (a PostHog `start_span` span, or the current OpenTelemetry span) stamps its data point with that span's trace ID, span ID, and value, so metric charts can link to a representative trace. One exemplar per series per flush window; the last sample wins. — Thanks @DanielVisca! + ## 7.68.0 — 2026-10-12 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index af1970c85..fdd21fd65 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.68.0" +VERSION = "7.69.0" diff --git a/pyproject.toml b/pyproject.toml index 037c8b5fa..6c1769aed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.68.0" +version = "7.69.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 0d70bd1e5..1dbe297aa 100644 --- a/uv.lock +++ b/uv.lock @@ -2490,7 +2490,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.102" +version = "0.1.103" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2820,7 +2820,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.68.0" +version = "7.69.0" source = { editable = "." } dependencies = [ { name = "distro" }, From 9e6955dc44b8c0f665a9d1434b54ba20a4399477 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:14:28 +0000 Subject: [PATCH 03/70] Update generated references (cherry picked from commit 6f658988e5b843c03ec73287677cae0f83b391e3) --- .../posthog-python-references-7.69.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.69.0.json diff --git a/references/posthog-python-references-7.69.0.json b/references/posthog-python-references-7.69.0.json new file mode 100644 index 000000000..d407afdb1 --- /dev/null +++ b/references/posthog-python-references-7.69.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.69.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely. Queued spans are sent at the same time, within the same", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name')\nposthog.flush() # Ensures the event is sent immediately" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Queued spans get one final flush of up to 30 s (plus a request already in flight); any it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Tell the client to flush all queued events.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import flush\nflush()" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index ef12885a8..d407afdb1 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.68.0", + "version": "7.69.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From be1aac59da9e339824ef59c3a4cca7a253226bd9 Mon Sep 17 00:00:00 2001 From: Carlos Marchal Date: Wed, 14 Oct 2026 18:52:19 +0200 Subject: [PATCH 04/70] feat(ai): add per-request context to span processor (#1060) * feat: span processor request context * fix: span processor review feedback * fix: span processor review follow-ups (cherry picked from commit 69164994c920bbaf445c3a2c20b9f558f6a5a473) --- .../span-processor-request-context.md | 5 + posthog/ai/otel/_request_context.py | 146 +++++++++ posthog/ai/otel/exporter.py | 2 + posthog/ai/otel/processor.py | 106 +++++- posthog/test/ai/otel/test_processor.py | 303 +++++++++++++++++- references/public_api_snapshot.txt | 1 + 6 files changed, 557 insertions(+), 6 deletions(-) create mode 100644 .sampo/changesets/span-processor-request-context.md create mode 100644 posthog/ai/otel/_request_context.py diff --git a/.sampo/changesets/span-processor-request-context.md b/.sampo/changesets/span-processor-request-context.md new file mode 100644 index 000000000..2d3b5f637 --- /dev/null +++ b/.sampo/changesets/span-processor-request-context.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +`PostHogSpanProcessor` now adds the active PostHog context to the AI spans it exports: the distinct ID from `identify_context`, the session ID from `set_context_session` (sent as `$session_id`), and context tags as properties. Spans started inside `posthog.new_context()` reach PostHog under the right person, so one process can trace many users. Tags set by the request middleware (for example `email`, `$ip`, `$user_agent` and `$current_url`) now appear on AI events too. Attributes already on a span are kept, and other processors on the provider never see the context. Apps already using PostHog contexts (for example the Django, Flask or ASGI request middleware) will see their AI events attributed to the context's person after upgrading. diff --git a/posthog/ai/otel/_request_context.py b/posthog/ai/otel/_request_context.py new file mode 100644 index 000000000..b34bf4c61 --- /dev/null +++ b/posthog/ai/otel/_request_context.py @@ -0,0 +1,146 @@ +"""Captures the active PostHog context for a span and applies it to an exported copy.""" + +import datetime +import decimal +import json +import logging +import math +import uuid +from dataclasses import dataclass +from typing import Any, Dict, Optional, Sequence + +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.util.types import AttributeValue + +from ...contexts import get_context_distinct_id, get_context_session_id, get_tags + +DISTINCT_ID_ATTRIBUTE = "posthog.distinct_id" +SESSION_ID_ATTRIBUTE = "$session_id" +# Ingestion prefers posthog.distinct_id, so adding the context's would override the span's explicit user. +IDENTITY_ATTRIBUTES = ( + DISTINCT_ID_ATTRIBUTE, + "user.id", + "ai.telemetry.metadata.posthog_distinct_id", + "ai.settings.context.posthog_distinct_id", +) +_MAX_INT64 = 2**63 - 1 +_MIN_INT64 = -(2**63) +_PRIMITIVE_TYPES = (str, bool, int, float) + +log = logging.getLogger("posthog") + + +@dataclass(frozen=True) +class RequestContext: + distinct_id: Optional[str] + session_id: Optional[str] + tags: Dict[str, Any] + + +def capture_request_context() -> Optional[RequestContext]: + """Snapshot the active context's distinct ID, session ID and tags, or None if all are empty.""" + snapshot = RequestContext( + distinct_id=get_context_distinct_id() or None, + session_id=get_context_session_id() or None, + tags=dict(get_tags()), + ) + if not (snapshot.distinct_id or snapshot.session_id or snapshot.tags): + return None + return snapshot + + +def request_context_attributes(context: RequestContext) -> Dict[str, AttributeValue]: + """Return the snapshot as span attributes. Tags win over the context IDs.""" + values: Dict[str, Any] = { + key: value + for key, value in ( + (DISTINCT_ID_ATTRIBUTE, context.distinct_id), + (SESSION_ID_ATTRIBUTE, context.session_id), + ) + if value + } + values.update(context.tags) + + attributes: Dict[str, AttributeValue] = {} + for key, value in values.items(): + try: + attribute = to_attribute_value(value) + except Exception: + log.debug("Failed to read PostHog context value %r", key, exc_info=True) + continue + if attribute is not None: + attributes[key] = attribute + return attributes + + +def with_request_context(span: ReadableSpan, context: RequestContext) -> ReadableSpan: + """Return a copy of ``span`` with the context's values added, keeping attributes it already has.""" + own = span.attributes or {} + has_identity = any(key in own for key in IDENTITY_ATTRIBUTES) + extra = { + key: value + for key, value in request_context_attributes(context).items() + if key not in own and not (has_identity and key == DISTINCT_ID_ATTRIBUTE) + } + if not extra: + return span + return ReadableSpan( + name=span.name, + context=span.get_span_context(), + parent=span.parent, + resource=span.resource, + attributes={**own, **extra}, + events=span.events, + links=span.links, + kind=span.kind, + status=span.status, + start_time=span.start_time, + end_time=span.end_time, + instrumentation_scope=span.instrumentation_scope, + ) + + +def to_attribute_value(value: Any) -> Optional[AttributeValue]: + """Return ``value`` as an OpenTelemetry attribute value, JSON-encoding anything OTel can't hold.""" + if value is None or (isinstance(value, str) and not value): + return None + if isinstance(value, float) and not math.isfinite(value): + return None + if _is_out_of_int64_range(value): + return str(value) + if isinstance(value, _PRIMITIVE_TYPES): + return value + if isinstance(value, (list, tuple)) and _is_homogeneous(value): + return list(value) + try: + encoded = json.dumps(value, allow_nan=False, default=_encode_string_like) + except (TypeError, ValueError): + return None + if encoded.startswith('"'): + return json.loads(encoded) or None + return encoded + + +def _encode_string_like(value: Any) -> str: + if isinstance(value, (datetime.datetime, datetime.date, datetime.time)): + return value.isoformat() + if isinstance(value, (uuid.UUID, decimal.Decimal)): + return str(value) + raise TypeError(f"{type(value).__name__} is not JSON serializable") + + +def _is_out_of_int64_range(value: Any) -> bool: + return ( + isinstance(value, int) + and not isinstance(value, bool) + and not _MIN_INT64 <= value <= _MAX_INT64 + ) + + +def _is_homogeneous(values: Sequence[Any]) -> bool: + return ( + all(isinstance(v, _PRIMITIVE_TYPES) for v in values) + and not any(_is_out_of_int64_range(v) for v in values) + and all(math.isfinite(v) for v in values if isinstance(v, float)) + and len({type(v) for v in values}) <= 1 + ) diff --git a/posthog/ai/otel/exporter.py b/posthog/ai/otel/exporter.py index 02c1c22e3..ec6e387ff 100644 --- a/posthog/ai/otel/exporter.py +++ b/posthog/ai/otel/exporter.py @@ -20,6 +20,8 @@ class PostHogTraceExporter(SpanExporter): Wraps an OTLPSpanExporter configured for PostHog's OTLP endpoint. Spans that are not AI-related are silently dropped, returning SUCCESS immediately. + Exporters only see finished spans, so they can't add per-request PostHog + context; use ``PostHogSpanProcessor`` for that. Usage:: diff --git a/posthog/ai/otel/processor.py b/posthog/ai/otel/processor.py index 4f520591b..31073c54b 100644 --- a/posthog/ai/otel/processor.py +++ b/posthog/ai/otel/processor.py @@ -5,7 +5,11 @@ for setups using TracerProvider.add_span_processor(). """ -from typing import Optional +import logging +import os +import threading +import weakref +from typing import Dict, Optional, Tuple from opentelemetry.context import Context from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor @@ -13,9 +17,43 @@ from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from ..gateway import warn_if_posthog_ai_gateway_otel_attributes +from ._request_context import ( + RequestContext, + capture_request_context, + with_request_context, +) from .spans import DEFAULT_HOST, is_ai_span +log = logging.getLogger("posthog") + + +def _span_key(span: ReadableSpan) -> Tuple[int, int]: + # The SDK passes on_end a ReadableSpan snapshot, not the Span object on_start saw. + context = span.get_span_context() + return (context.trace_id, context.span_id) + + +_processors: "weakref.WeakSet[PostHogSpanProcessor]" = weakref.WeakSet() + + +def _discard_abandoned( + processor_ref: "weakref.ref[PostHogSpanProcessor]", key: Tuple[int, int] +) -> None: + processor = processor_ref() + if processor is not None: + processor._discard_captured(key) + + +def _reset_processors_after_fork() -> None: + for processor in list(_processors): + processor._reset_after_fork() + + +if hasattr(os, "register_at_fork"): + os.register_at_fork(after_in_child=_reset_processors_after_fork) + + class PostHogSpanProcessor(SpanProcessor): """Span processor that filters AI spans and exports them to PostHog. @@ -32,6 +70,19 @@ class PostHogSpanProcessor(SpanProcessor): provider.add_span_processor( PostHogSpanProcessor(api_key="phc_...") ) + + # Per request: AI spans started inside a context export with its user, session and tags. + with posthog.new_context(): + posthog.identify_context(user_id) + posthog.tag("plan", "pro") + handle_request() + + Attributes already on a span win over explicit tags, which win over the + context's distinct ID and session ID (exported as ``$session_id``). Threads that don't copy contextvars + carry no user. + + The context is captured when a span starts, but tag values are read when the + span ends. Mutating a tagged object while a span is open shows up in the export. """ def __init__( @@ -52,15 +103,50 @@ def __init__( headers={"Authorization": f"Bearer {self._api_key}"}, ) self._processor = BatchSpanProcessor(exporter) + self._captured: Dict[ + Tuple[int, int], Tuple[RequestContext, weakref.finalize] + ] = {} + # Reentrant: cyclic GC can run a span finalizer on a thread that already holds the lock. + self._captured_lock = threading.RLock() + _processors.add(self) + + def _reset_after_fork(self) -> None: + # A lock held by another thread at fork time would never release in the child. + self._captured_lock = threading.RLock() + self._captured = {} + + def _discard_captured(self, key: Tuple[int, int]) -> None: + with self._captured_lock: + self._captured.pop(key, None) + + def _take_captured(self, key: Tuple[int, int]) -> Optional[RequestContext]: + with self._captured_lock: + entry = self._captured.pop(key, None) + if entry is None: + return None + captured, finalizer = entry + finalizer.detach() + return captured def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None: """ - Handle span start notifications. + Remember the active PostHog context for the span. - This processor does not need to do work at span start; filtering happens - in ``on_end``. + The span itself is left untouched, so other processors on the provider + never see the context. The values are added to the copy exported to + PostHog in ``on_end``. """ - pass + try: + captured = capture_request_context() + if captured: + key = _span_key(span) + finalizer = weakref.finalize( + span, _discard_abandoned, weakref.ref(self), key + ) + with self._captured_lock: + self._captured[key] = (captured, finalizer) + except Exception: + log.debug("Failed to capture PostHog context for span", exc_info=True) def on_end(self, span: ReadableSpan) -> None: """ @@ -69,14 +155,24 @@ def on_end(self, span: ReadableSpan) -> None: Args: span: The ended OpenTelemetry span. """ + captured = self._take_captured(_span_key(span)) if not is_ai_span(span): return warn_if_posthog_ai_gateway_otel_attributes(span.attributes) + if captured: + try: + span = with_request_context(span, captured) + except Exception: + log.debug("Failed to add PostHog context to span", exc_info=True) self._processor.on_end(span) def shutdown(self) -> None: """Shut down the underlying batch span processor.""" self._processor.shutdown() + with self._captured_lock: + for _, finalizer in self._captured.values(): + finalizer.detach() + self._captured.clear() def force_flush(self, timeout_millis: Optional[int] = None) -> bool: """ diff --git a/posthog/test/ai/otel/test_processor.py b/posthog/test/ai/otel/test_processor.py index c2e2c2694..06deb61a2 100644 --- a/posthog/test/ai/otel/test_processor.py +++ b/posthog/test/ai/otel/test_processor.py @@ -1,7 +1,17 @@ +import gc +import json +import threading import unittest +import uuid +from datetime import datetime, timezone +from decimal import Decimal +from concurrent.futures import ThreadPoolExecutor from unittest.mock import MagicMock, patch -from posthog.ai.otel.processor import PostHogSpanProcessor +from opentelemetry.sdk.trace import TracerProvider + +from posthog import contexts +from posthog.ai.otel.processor import PostHogSpanProcessor, _reset_processors_after_fork from posthog.test.ai.otel.conftest import make_span @@ -108,3 +118,294 @@ def test_force_flush_without_timeout(self, mock_batch_cls, mock_otlp_cls): inner.force_flush.return_value = result self.assertIs(processor.force_flush(), result) inner.force_flush.assert_called_once_with() + + +def new_request_context(): + return contexts.new_context(fresh=True, capture_exceptions=False) + + +class TestPostHogSpanProcessorRequestContext(unittest.TestCase): + def setUp(self): + exporter_patch = patch("posthog.ai.otel.processor.OTLPSpanExporter") + batch_patch = patch("posthog.ai.otel.processor.BatchSpanProcessor") + exporter_patch.start() + self.inner = batch_patch.start().return_value + self.addCleanup(exporter_patch.stop) + self.addCleanup(batch_patch.stop) + provider = TracerProvider() + self.processor = PostHogSpanProcessor(api_key="phc_test") + provider.add_span_processor(self.processor) + self.other_processor = MagicMock() + provider.add_span_processor(self.other_processor) + self.tracer = provider.get_tracer("test") + + def _emit_span(self, name="gen_ai.chat", attributes=None): + with self.tracer.start_as_current_span(name, attributes=attributes): + pass + + def _exported_attributes(self): + return [ + dict(call.args[0].attributes) for call in self.inner.on_end.call_args_list + ] + + def test_exports_distinct_id_session_and_tags(self): + with new_request_context(): + contexts.identify_context("alice") + contexts.set_context_session("s_alice") + contexts.tag("plan", "pro") + self._emit_span() + + self.assertEqual( + self._exported_attributes(), + [ + { + "posthog.distinct_id": "alice", + "$session_id": "s_alice", + "plan": "pro", + } + ], + ) + + def test_other_processors_do_not_see_the_context(self): + with new_request_context(): + contexts.identify_context("alice") + contexts.tag("plan", "pro") + self._emit_span(attributes={"gen_ai.system": "openai"}) + + started = self.other_processor.on_start.call_args.args[0] + ended = self.other_processor.on_end.call_args.args[0] + self.assertEqual(dict(started.attributes), {"gen_ai.system": "openai"}) + self.assertEqual(dict(ended.attributes), {"gen_ai.system": "openai"}) + + def test_drops_non_ai_spans_started_in_a_context(self): + with new_request_context(): + contexts.identify_context("alice") + self._emit_span(name="http.request") + + self.inner.on_end.assert_not_called() + self.assertEqual(self.processor._captured, {}) + + def test_shutdown_clears_captured_contexts(self): + with new_request_context(): + contexts.identify_context("alice") + with self.tracer.start_as_current_span("gen_ai.chat"): + self.assertEqual(len(self.processor._captured), 1) + self.processor.shutdown() + self.assertEqual(self.processor._captured, {}) + + def test_keeps_attributes_already_on_the_span(self): + with new_request_context(): + contexts.set_context_session("s_alice") + self._emit_span(attributes={"$session_id": "conv_42"}) + + self.assertEqual(self._exported_attributes()[0]["$session_id"], "conv_42") + + def test_skips_context_distinct_id_when_span_has_an_identity(self): + identity_keys = ( + "posthog.distinct_id", + "user.id", + "ai.telemetry.metadata.posthog_distinct_id", + "ai.settings.context.posthog_distinct_id", + ) + for key in identity_keys: + with self.subTest(key=key): + self.inner.on_end.reset_mock() + with new_request_context(): + contexts.identify_context("alice") + self._emit_span(attributes={key: "bob"}) + + attributes = self._exported_attributes()[0] + self.assertEqual(attributes[key], "bob") + if key != "posthog.distinct_id": + self.assertNotIn("posthog.distinct_id", attributes) + + def test_skips_distinct_id_tag_when_span_has_an_identity(self): + with new_request_context(): + contexts.tag("posthog.distinct_id", "alice") + self._emit_span(attributes={"user.id": "bob"}) + + attributes = self._exported_attributes()[0] + self.assertEqual(attributes, {"user.id": "bob"}) + + def test_encodes_structured_tags_as_json(self): + with new_request_context(): + contexts.tag("account", {"tier": "pro", "seats": 3}) + contexts.tag("arms", ["short-prompt", "new-router"]) + contexts.tag("mixed", ["a", 1]) + contexts.tag("nested_not_finite", {"x": float("inf")}) + self._emit_span() + + attributes = self._exported_attributes()[0] + self.assertEqual(json.loads(attributes["account"]), {"tier": "pro", "seats": 3}) + self.assertEqual(list(attributes["arms"]), ["short-prompt", "new-router"]) + self.assertEqual(json.loads(attributes["mixed"]), ["a", 1]) + self.assertNotIn("nested_not_finite", attributes) + + def test_skips_non_finite_numbers(self): + with new_request_context(): + contexts.tag("nan", float("nan")) + contexts.tag("inf", float("-inf")) + contexts.tag("list_with_inf", [1.0, float("inf")]) + contexts.tag("plan", "pro") + self._emit_span() + + self.assertEqual(self._exported_attributes(), [{"plan": "pro"}]) + + def test_string_like_values_arrive_as_plain_strings(self): + moment = datetime(2026, 10, 14, 8, 30, tzinfo=timezone.utc) + identifier = uuid.UUID("12345678-1234-5678-1234-567812345678") + with new_request_context(): + contexts.tag("when", moment) + contexts.tag("id", identifier) + contexts.tag("price", Decimal("1.50")) + self._emit_span() + + self.assertEqual( + self._exported_attributes(), + [{"when": moment.isoformat(), "id": str(identifier), "price": "1.50"}], + ) + + def test_skips_values_json_cannot_represent(self): + with new_request_context(): + contexts.tag("tags", {"a", "b"}) + contexts.tag("raw", b"bytes") + contexts.tag("plan", "pro") + self._emit_span() + + self.assertEqual(self._exported_attributes(), [{"plan": "pro"}]) + + def test_tags_win_over_context_ids_and_survive_an_empty_context(self): + with new_request_context(): + contexts.tag("$session_id", "conv_42") + self._emit_span() + with new_request_context(): + contexts.set_context_session("s_alice") + contexts.tag("$session_id", "conv_42") + self._emit_span() + + self.assertEqual( + [a["$session_id"] for a in self._exported_attributes()], + ["conv_42", "conv_42"], + ) + + def test_explicit_ai_session_id_tag_passes_through(self): + with new_request_context(): + contexts.set_context_session("s_alice") + contexts.tag("$ai_session_id", "conv_42") + self._emit_span() + + attributes = self._exported_attributes()[0] + self.assertEqual(attributes["$ai_session_id"], "conv_42") + self.assertEqual(attributes["$session_id"], "s_alice") + + def test_context_session_does_not_set_ai_session_id(self): + with new_request_context(): + contexts.set_context_session("s_alice") + self._emit_span() + + self.assertNotIn("$ai_session_id", self._exported_attributes()[0]) + + def test_integers_outside_signed_64_bit_range_are_sent_as_strings(self): + with new_request_context(): + contexts.tag("big", 2**63) + contexts.tag("small", -(2**63) - 1) + contexts.tag("edge", 2**63 - 1) + contexts.tag("bigs", [2**64, 1]) + self._emit_span() + + attributes = self._exported_attributes()[0] + self.assertEqual(attributes["big"], str(2**63)) + self.assertEqual(attributes["small"], str(-(2**63) - 1)) + self.assertEqual(attributes["edge"], 2**63 - 1) + self.assertEqual(json.loads(attributes["bigs"]), [2**64, 1]) + + def test_abandoned_span_entry_is_removed_when_garbage_collected(self): + with new_request_context(): + contexts.identify_context("alice") + span = self.tracer.start_span("gen_ai.chat") + self.assertEqual(len(self.processor._captured), 1) + + self.other_processor.reset_mock() + del span + gc.collect() + + self.assertEqual(self.processor._captured, {}) + + def test_collecting_an_abandoned_span_does_not_deadlock_on_the_held_lock(self): + def collect_while_holding_lock(): + with new_request_context(): + contexts.identify_context("alice") + holder = [] + span = self.tracer.start_span("gen_ai.chat") + holder.append(span) + holder.append(holder) + del span, holder + self.other_processor.reset_mock() + with self.processor._captured_lock: + gc.collect() + + worker = threading.Thread(target=collect_while_holding_lock, daemon=True) + worker.start() + worker.join(timeout=5) + + self.assertFalse(worker.is_alive(), "gc deadlocked on the captured lock") + self.assertEqual(self.processor._captured, {}) + + def test_finalizer_is_detached_once_the_span_ends(self): + with new_request_context(): + contexts.identify_context("alice") + span = self.tracer.start_span("gen_ai.chat") + _, finalizer = next(iter(self.processor._captured.values())) + self.assertTrue(finalizer.alive) + + span.end() + + self.assertFalse(finalizer.alive) + self.assertEqual(self.processor._captured, {}) + + def test_after_fork_resets_lock_and_store(self): + with new_request_context(): + contexts.identify_context("alice") + span = self.tracer.start_span("gen_ai.chat") + old_lock = self.processor._captured_lock + + _reset_processors_after_fork() + + self.assertIsNot(self.processor._captured_lock, old_lock) + self.assertEqual(self.processor._captured, {}) + span.end() + + def test_unstampable_tag_does_not_drop_the_other_tags(self): + class Unstampable(list): + def __iter__(self): + raise RuntimeError("cannot iterate") + + with new_request_context(): + contexts.tag("bad", Unstampable([1])) + contexts.tag("plan", "pro") + self._emit_span() + + self.assertEqual(self._exported_attributes(), [{"plan": "pro"}]) + + def test_adds_nothing_without_a_context(self): + self._emit_span() + + self.assertEqual(self._exported_attributes(), [{}]) + + def test_overlapping_requests_export_their_own_values(self): + both_started = threading.Barrier(2) + + def request(user): + with new_request_context(): + contexts.identify_context(user) + span = self.tracer.start_span("gen_ai.chat") + both_started.wait(timeout=5) + span.end() + + with ThreadPoolExecutor(max_workers=2) as pool: + list(pool.map(request, ["alice", "bob"])) + + self.assertEqual( + sorted(a["posthog.distinct_id"] for a in self._exported_attributes()), + ["alice", "bob"], + ) diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index 262287f3b..55c54fa34 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -554,6 +554,7 @@ attribute posthog.ai.openai.openai_providers.AzureOpenAI.embeddings: WrappedEmbe attribute posthog.ai.openai.openai_providers.AzureOpenAI.responses: WrappedResponses attribute posthog.ai.openai.wrapper_utils.log = logging.getLogger('posthog') attribute posthog.ai.openai_agents.processor.log = logging.getLogger('posthog') +attribute posthog.ai.otel.processor.log = logging.getLogger('posthog') attribute posthog.ai.otel.spans.AI_SPAN_PREFIXES = ('gen_ai.', 'llm.', 'ai.', 'traceloop.') attribute posthog.ai.otel.spans.DEFAULT_HOST = 'https://us.i.posthog.com' attribute posthog.ai.prompts.APP_ENDPOINT = 'https://us.posthog.com' From f91badaada9324982f291e44f34af7d0a29b8bfc Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:54:22 +0000 Subject: [PATCH 05/70] chore: Release v7.70.0 [skip ci] (cherry picked from commit a615eed8fb157f4dfa5e4d141a998c137c4b9ba3) --- .sampo/changesets/span-processor-request-context.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/span-processor-request-context.md diff --git a/.sampo/changesets/span-processor-request-context.md b/.sampo/changesets/span-processor-request-context.md deleted file mode 100644 index 2d3b5f637..000000000 --- a/.sampo/changesets/span-processor-request-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -`PostHogSpanProcessor` now adds the active PostHog context to the AI spans it exports: the distinct ID from `identify_context`, the session ID from `set_context_session` (sent as `$session_id`), and context tags as properties. Spans started inside `posthog.new_context()` reach PostHog under the right person, so one process can trace many users. Tags set by the request middleware (for example `email`, `$ip`, `$user_agent` and `$current_url`) now appear on AI events too. Attributes already on a span are kept, and other processors on the provider never see the context. Apps already using PostHog contexts (for example the Django, Flask or ASGI request middleware) will see their AI events attributed to the context's person after upgrading. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index a187f190f..6e16d0a07 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.104 — 2026-10-14 + +### Patch changes + +- Updated dependencies: posthog@7.70.0 + ## 0.1.103 — 2026-10-13 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index f1710339d..4a214fe84 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.103" +version = "0.1.104" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 424723c31..b6e350fdf 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.70.0 — 2026-10-14 + +### Minor changes + +- [6916499](https://github.com/posthog/posthog-python/commit/69164994c920bbaf445c3a2c20b9f558f6a5a473) `PostHogSpanProcessor` now adds the active PostHog context to the AI spans it exports: the distinct ID from `identify_context`, the session ID from `set_context_session` (sent as `$session_id`), and context tags as properties. Spans started inside `posthog.new_context()` reach PostHog under the right person, so one process can trace many users. Tags set by the request middleware (for example `email`, `$ip`, `$user_agent` and `$current_url`) now appear on AI events too. Attributes already on a span are kept, and other processors on the provider never see the context. Apps already using PostHog contexts (for example the Django, Flask or ASGI request middleware) will see their AI events attributed to the context's person after upgrading. — Thanks @carlos-marchal-ph! + ## 7.69.0 — 2026-10-13 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index fdd21fd65..76c542202 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.69.0" +VERSION = "7.70.0" diff --git a/pyproject.toml b/pyproject.toml index 6c1769aed..cb7165924 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.69.0" +version = "7.70.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 1dbe297aa..f672e8b8b 100644 --- a/uv.lock +++ b/uv.lock @@ -2490,7 +2490,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.103" +version = "0.1.104" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2820,7 +2820,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.69.0" +version = "7.70.0" source = { editable = "." } dependencies = [ { name = "distro" }, From 976f41bd6d7d1f37271a314fde686ecfc408f9bb Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:54:27 +0000 Subject: [PATCH 06/70] Update generated references (cherry picked from commit a49648e0a0f9842914df91c3d2790ad9e4edca71) --- .../posthog-python-references-7.70.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.70.0.json diff --git a/references/posthog-python-references-7.70.0.json b/references/posthog-python-references-7.70.0.json new file mode 100644 index 000000000..6e46c32c7 --- /dev/null +++ b/references/posthog-python-references-7.70.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.70.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely. Queued spans are sent at the same time, within the same", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name')\nposthog.flush() # Ensures the event is sent immediately" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Queued spans get one final flush of up to 30 s (plus a request already in flight); any it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Tell the client to flush all queued events.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import flush\nflush()" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index d407afdb1..6e46c32c7 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.69.0", + "version": "7.70.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From e636251807f317bc5a299eacbc0dd6842d0bc829 Mon Sep 17 00:00:00 2001 From: Juraj Majerik Date: Thu, 15 Oct 2026 17:11:41 +0200 Subject: [PATCH 07/70] fix(prompts): share one request between concurrent fetches of the same prompt (#1059) (cherry picked from commit 10d094e384efce1422ae1853951b7d2eaa0885ef) --- .sampo/changesets/prompts-single-flight.md | 5 + posthog/ai/prompts.py | 147 ++++++++++++++++----- posthog/test/ai/test_prompts.py | 120 +++++++++++++++++ 3 files changed, 240 insertions(+), 32 deletions(-) create mode 100644 .sampo/changesets/prompts-single-flight.md diff --git a/.sampo/changesets/prompts-single-flight.md b/.sampo/changesets/prompts-single-flight.md new file mode 100644 index 000000000..6051ac9b1 --- /dev/null +++ b/.sampo/changesets/prompts-single-flight.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +`Prompts.get()` now makes one request when several threads ask for the same prompt at once, instead of one request per thread. The other threads wait for that result. With `capture_errors=True`, a shared failure is reported once instead of once per thread. diff --git a/posthog/ai/prompts.py b/posthog/ai/prompts.py index c62841561..4da454703 100644 --- a/posthog/ai/prompts.py +++ b/posthog/ai/prompts.py @@ -7,10 +7,13 @@ import copy import logging import math +import os import re +import threading import time import urllib.parse import warnings +import weakref from dataclasses import dataclass from typing import Any, Dict, List, Literal, Optional, Union, overload @@ -37,6 +40,33 @@ PromptSource = Literal["api", "cache", "stale_cache", "code_fallback"] +class _InFlightFetch: + """One network request that several callers wait on.""" + + def __init__(self) -> None: + self.done = threading.Event() + self.result: Optional[CachedPrompt] = None + self.error: Optional[BaseException] = None + + +# Every live Prompts instance, so one fork hook can reset them all. Registered +# once here, because os.register_at_fork keeps each callback for the process +# lifetime and an app that builds many instances would accumulate them. +_instances: "weakref.WeakSet[Prompts]" = weakref.WeakSet() + + +def _reset_in_flight_after_fork() -> None: + # The child has no copy of the thread that was fetching, so an inherited + # in-flight entry would hold every later caller for that key. + for prompts in list(_instances): + prompts._in_flight = {} + prompts._in_flight_lock = threading.Lock() + + +if hasattr(os, "register_at_fork"): + os.register_at_fork(after_in_child=_reset_in_flight_after_fork) + + @dataclass(frozen=True) class PromptResult: """Result of a prompt fetch with metadata about its source. @@ -270,6 +300,12 @@ def __init__( else DEFAULT_CACHE_TTL_SECONDS ) self._cache: Dict[PromptCacheKey, CachedPrompt] = {} + # One request per cache key at a time. Threads that arrive while it is in + # flight wait for that result, so a worker with many concurrent callers does + # not turn every cache miss or expiry into one request per caller. + self._in_flight: Dict[PromptCacheKey, _InFlightFetch] = {} + self._in_flight_lock = threading.Lock() + _instances.add(self) self._has_warned_deprecation = False self._client = posthog self._capture_errors = capture_errors @@ -568,44 +604,18 @@ def _get_internal( # Try to fetch from API try: - data = self._fetch_prompt_from_api(name, version, label) - - # An older PostHog server ignores the label param and returns the latest - # version with no label field — surface that instead of failing silently. - if label is not None and data.get("label") != label: - log.warning( - "[PostHog Prompts] Requested label %r for prompt %r but the server " - "resolved %r. It may not support prompt labels yet and returned the " - "latest version instead.", - label, - name, - data.get("label"), - ) - - config = _extract_config(data) - - # Update cache - self._cache[cache_key] = CachedPrompt( - prompt=data["prompt"], - fetched_at=time.time(), - name=data["name"], - version=data["version"], - label=data.get("label"), - config=config, - ) + fetched = self._fetch_prompt_once(name, version, label, ttl=ttl) return PromptResult( source="api", - prompt=data["prompt"], - name=data["name"], - version=data["version"], - label=data.get("label"), - config=copy.deepcopy(config), + prompt=fetched.prompt, + name=fetched.name, + version=fetched.version, + label=fetched.label, + config=copy.deepcopy(fetched.config), ) except Exception as error: - self._maybe_capture_error(error, name=name, version=version, label=label) - prompt_reference = _prompt_reference(name, version, label) # Return stale cache (with warning) if cached is not None: @@ -634,6 +644,79 @@ def _get_internal( raise + def _fetch_prompt_once( + self, + name: str, + version: Optional[int], + label: Optional[str], + *, + ttl: float, + ) -> CachedPrompt: + """Fetch a prompt, sharing the request with other threads that want the same key.""" + cache_key = _cache_key(name, version, label) + with self._in_flight_lock: + # Another thread may have finished a fetch between the caller's cache + # check and this lock. Its entry is fresh, so serve it instead of + # starting another request. A zero TTL is never fresh and still fetches. + cached = self._cache.get(cache_key) + if cached is not None and (time.time() - cached.fetched_at) < ttl: + return cached + + pending = self._in_flight.get(cache_key) + is_leader = pending is None + if pending is None: + pending = _InFlightFetch() + self._in_flight[cache_key] = pending + + if not is_leader: + pending.done.wait() + if pending.error is not None: + raise pending.error + assert pending.result is not None + return pending.result + + try: + data = self._fetch_prompt_from_api(name, version, label) + + # An older PostHog server ignores the label param and returns the latest + # version with no label field — surface that instead of failing silently. + if label is not None and data.get("label") != label: + log.warning( + "[PostHog Prompts] Requested label %r for prompt %r but the server " + "resolved %r. It may not support prompt labels yet and returned the " + "latest version instead.", + label, + name, + data.get("label"), + ) + + fetched = CachedPrompt( + prompt=data["prompt"], + fetched_at=time.time(), + name=data["name"], + version=data["version"], + label=data.get("label"), + config=_extract_config(data), + ) + # Cached before the in-flight entry is released, so a caller that + # arrives in between finds the entry instead of starting a request. + self._cache[cache_key] = fetched + pending.result = fetched + return fetched + except BaseException as error: + pending.error = error + raise + finally: + with self._in_flight_lock: + self._in_flight.pop(cache_key, None) + pending.done.set() + # Reported after the waiters are released, so an error-tracking callback + # that fetches the same prompt cannot wait on this very request. + if isinstance(pending.error, Exception): + self._maybe_capture_error( + pending.error, name=name, version=version, label=label + ) + def compile(self, prompt: str, variables: PromptVariables) -> str: """ Replace {{variableName}} placeholders with values. diff --git a/posthog/test/ai/test_prompts.py b/posthog/test/ai/test_prompts.py index 4e124f16d..7072bc90c 100644 --- a/posthog/test/ai/test_prompts.py +++ b/posthog/test/ai/test_prompts.py @@ -1,3 +1,4 @@ +import threading import unittest import warnings from unittest.mock import MagicMock, patch @@ -382,6 +383,125 @@ def test_hold_a_cooldown_after_each_failed_refetch( self.assertEqual(result.source, "api") self.assertEqual(mock_get.call_count, 4) + def _run_concurrent_gets(self, prompts, calls): + results = [None] * len(calls) + start_together = threading.Barrier(len(calls)) + + def run(index, kwargs): + start_together.wait(5) + results[index] = prompts.get("test-prompt", with_metadata=True, **kwargs) + + threads = [ + threading.Thread(target=run, args=(index, kwargs)) + for index, kwargs in enumerate(calls) + ] + for thread in threads: + thread.start() + for thread in threads: + thread.join(timeout=5) + return results + + @patch("posthog.ai.prompts._get_session") + def test_share_one_request_between_concurrent_callers(self, mock_get_session): + mock_get = mock_get_session.return_value.get + release = threading.Event() + + def slow_get(url, **kwargs): + release.wait(5) + version = 2 if "version=2" in url else 1 + return MockResponse( + json_data={**self.mock_prompt_response, "version": version} + ) + + mock_get.side_effect = slow_get + prompts = Prompts(self.create_mock_posthog()) + + calls = [{}] * 10 + [{"version": 2}] + + # Release the network once every caller is waiting on it. + timer = threading.Timer(0.2, release.set) + timer.start() + results = self._run_concurrent_gets(prompts, calls) + timer.join() + + self.assertEqual(mock_get.call_count, 2) + self.assertEqual({r.source for r in results}, {"api"}) + self.assertEqual([r.version for r in results[:10]], [1] * 10) + self.assertEqual(results[10].version, 2) + + @patch("posthog.ai.prompts._get_session") + def test_concurrent_callers_share_one_failure_and_capture_it_once( + self, mock_get_session + ): + mock_get = mock_get_session.return_value.get + release = threading.Event() + + def failing_get(url, **kwargs): + release.wait(5) + raise Exception("Network error") + + mock_get.side_effect = failing_get + posthog = self.create_mock_posthog() + prompts = Prompts(posthog, capture_errors=True) + + timer = threading.Timer(0.2, release.set) + timer.start() + results = self._run_concurrent_gets( + prompts, [{"fallback": "fallback prompt"}] * 10 + ) + timer.join() + + self.assertEqual(mock_get.call_count, 1) + self.assertEqual({r.source for r in results}, {"code_fallback"}) + posthog.capture_exception.assert_called_once() + + @patch("posthog.ai.prompts._get_session") + def test_fork_hook_clears_inherited_in_flight_entries(self, mock_get_session): + from posthog.ai.prompts import ( + _InFlightFetch, + _cache_key, + _reset_in_flight_after_fork, + ) + + mock_get = mock_get_session.return_value.get + mock_get.return_value = MockResponse(json_data=self.mock_prompt_response) + prompts = Prompts(self.create_mock_posthog()) + # What a forked child inherits: an entry whose fetching thread no longer exists. + prompts._in_flight[_cache_key("test-prompt", None, None)] = _InFlightFetch() + + _reset_in_flight_after_fork() + result = prompts.get("test-prompt", with_metadata=True) + + self.assertEqual(result.source, "api") + self.assertEqual(mock_get.call_count, 1) + + @patch("posthog.ai.prompts._get_session") + def test_error_callback_that_fetches_the_same_prompt_does_not_deadlock( + self, mock_get_session + ): + mock_get = mock_get_session.return_value.get + mock_get.side_effect = Exception("Network error") + posthog = self.create_mock_posthog() + prompts = Prompts(posthog, capture_errors=True) + nested_results = [] + entered = threading.Event() + + def capture_exception(*args, **kwargs): + # The nested fetch fails too and reports again; only the first report fetches. + if entered.is_set(): + return + entered.set() + nested_results.append( + prompts.get("test-prompt", with_metadata=True, fallback="nested") + ) + + posthog.capture_exception.side_effect = capture_exception + + result = prompts.get("test-prompt", with_metadata=True, fallback="outer") + + self.assertEqual(result.prompt, "outer") + self.assertEqual([r.prompt for r in nested_results], ["nested"]) + @patch("posthog.ai.prompts._get_session") @patch("posthog.ai.prompts.log") def test_use_fallback_when_no_cache_and_fetch_fails_with_warning( From 401cf67e694de017fd4f07bb195f5639c2edda66 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 16:07:14 +0000 Subject: [PATCH 08/70] chore: Release v7.70.1 [skip ci] (cherry picked from commit ec71a24065b34fb326f5022a9c0225398f82ec75) --- .sampo/changesets/prompts-single-flight.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/prompts-single-flight.md diff --git a/.sampo/changesets/prompts-single-flight.md b/.sampo/changesets/prompts-single-flight.md deleted file mode 100644 index 6051ac9b1..000000000 --- a/.sampo/changesets/prompts-single-flight.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -`Prompts.get()` now makes one request when several threads ask for the same prompt at once, instead of one request per thread. The other threads wait for that result. With `capture_errors=True`, a shared failure is reported once instead of once per thread. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 6e16d0a07..d1e981944 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.105 — 2026-10-15 + +### Patch changes + +- Updated dependencies: posthog@7.70.1 + ## 0.1.104 — 2026-10-14 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 4a214fe84..52b9920d9 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.104" +version = "0.1.105" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index b6e350fdf..7dbe1ba87 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.70.1 — 2026-10-15 + +### Patch changes + +- [10d094e](https://github.com/posthog/posthog-python/commit/10d094e384efce1422ae1853951b7d2eaa0885ef) `Prompts.get()` now makes one request when several threads ask for the same prompt at once, instead of one request per thread. The other threads wait for that result. With `capture_errors=True`, a shared failure is reported once instead of once per thread. — Thanks @jurajmajerik! + ## 7.70.0 — 2026-10-14 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index 76c542202..b4fa8dd98 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.70.0" +VERSION = "7.70.1" diff --git a/pyproject.toml b/pyproject.toml index cb7165924..0332a2142 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.70.0" +version = "7.70.1" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index f672e8b8b..fb55693ce 100644 --- a/uv.lock +++ b/uv.lock @@ -2490,7 +2490,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.104" +version = "0.1.105" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2820,7 +2820,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.0" +version = "7.70.1" source = { editable = "." } dependencies = [ { name = "distro" }, From e91b6d5ce3d34843fdc1e91f9e7d45c0490a9308 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 16:07:20 +0000 Subject: [PATCH 09/70] Update generated references (cherry picked from commit fc3c4347d3371dc84dc4ea0276d3355c353a2eb7) --- .../posthog-python-references-7.70.1.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.70.1.json diff --git a/references/posthog-python-references-7.70.1.json b/references/posthog-python-references-7.70.1.json new file mode 100644 index 000000000..affb9655a --- /dev/null +++ b/references/posthog-python-references-7.70.1.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.70.1", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely. Queued spans are sent at the same time, within the same", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name')\nposthog.flush() # Ensures the event is sent immediately" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Queued spans get one final flush of up to 30 s (plus a request already in flight); any it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Tell the client to flush all queued events.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import flush\nflush()" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 6e46c32c7..affb9655a 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.70.0", + "version": "7.70.1", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 05af454240394a5cc1d5db13b674a8fb51655411 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Date: Thu, 15 Oct 2026 23:59:18 +0700 Subject: [PATCH 10/70] fix(ai): mark cancelled async LLM calls as errors (#1065) * fix(ai): mark cancelled async LLM calls as errors * test: fix Python 3.10 cancellation and FastMCP compatibility (cherry picked from commit fec41f24cb497d37a8cd0dd53490b74c98554dfa) --- .../venerable-baroness-lemminkainen.md | 5 ++ posthog/ai/utils.py | 8 ++ posthog/test/ai/gemini/test_gemini_async.py | 27 ++++++ posthog/test/ai/test_async_cancellation.py | 87 +++++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 .sampo/changesets/venerable-baroness-lemminkainen.md create mode 100644 posthog/test/ai/test_async_cancellation.py diff --git a/.sampo/changesets/venerable-baroness-lemminkainen.md b/.sampo/changesets/venerable-baroness-lemminkainen.md new file mode 100644 index 000000000..5dc5c3502 --- /dev/null +++ b/.sampo/changesets/venerable-baroness-lemminkainen.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Mark cancelled async LLM calls as errors while preserving cancellation. diff --git a/posthog/ai/utils.py b/posthog/ai/utils.py index 3c86df05d..e67ab2d21 100644 --- a/posthog/ai/utils.py +++ b/posthog/ai/utils.py @@ -1,3 +1,4 @@ +import asyncio import logging import time import uuid @@ -681,6 +682,13 @@ async def call_llm_and_track_usage_async( try: response = await call_async_method(**kwargs) + except asyncio.CancelledError: + http_status = 0 + error_params = { + "$ai_is_error": True, + "$ai_error": "cancelled", + } + raise except Exception as exc: error = exc http_status = getattr( diff --git a/posthog/test/ai/gemini/test_gemini_async.py b/posthog/test/ai/gemini/test_gemini_async.py index 701b7ebdc..ed07f0d6d 100644 --- a/posthog/test/ai/gemini/test_gemini_async.py +++ b/posthog/test/ai/gemini/test_gemini_async.py @@ -1,3 +1,4 @@ +import asyncio import os from unittest.mock import AsyncMock, MagicMock, patch @@ -150,6 +151,32 @@ async def test_async_client_basic_generation( assert props["$ai_latency"] > 0 +async def test_async_client_timeout_captures_error( + mock_client, mock_google_genai_client +): + async def slow_call(**kwargs): + await asyncio.Event().wait() + + mock_google_genai_client.aio.models.generate_content = AsyncMock( + side_effect=slow_call + ) + client = AsyncClient(api_key="test-key", posthog_client=mock_client) + + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait_for( + client.models.generate_content(model="gemini-x", contents="Hello"), + timeout=0.01, + ) + + assert mock_client.capture_ai.call_count == 1 + event = mock_client.capture_ai.call_args.kwargs + assert event["event"] == "$ai_generation" + props = event["properties"] + assert props["$ai_http_status"] == 0 + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "cancelled" + + async def test_async_client_streaming_with_generate_content_stream( mock_client, mock_google_genai_client ): diff --git a/posthog/test/ai/test_async_cancellation.py b/posthog/test/ai/test_async_cancellation.py new file mode 100644 index 000000000..f247bbcdf --- /dev/null +++ b/posthog/test/ai/test_async_cancellation.py @@ -0,0 +1,87 @@ +import asyncio + +import pytest + +from posthog import Posthog +from posthog.ai.utils import call_llm_and_track_usage_async + + +@pytest.fixture +def captured_generations(): + events = [] + + def before_send(event): + if event["event"] == "$ai_generation": + events.append(event) + return None + + client = Posthog("phc_test", before_send=before_send, sync_mode=True) + try: + yield client, events + finally: + client.shutdown() + + +@pytest.mark.asyncio +@pytest.mark.parametrize("provider", ["gemini", "openai", "anthropic"]) +async def test_cancelled_call_captures_error_and_preserves_cancellation( + captured_generations, provider +): + client, events = captured_generations + started = asyncio.Event() + + async def slow_call(**kwargs): + started.set() + await asyncio.Event().wait() + + task = asyncio.create_task( + call_llm_and_track_usage_async( + "user-1", + client, + provider, + "trace-1", + None, + False, + None, + "", + slow_call, + model="test-model", + ) + ) + await started.wait() + task.cancel("request cancelled") + + with pytest.raises(asyncio.CancelledError): + await task + + assert task.cancelled() + assert len(events) == 1 + props = events[0]["properties"] + assert props["$ai_http_status"] == 0 + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "cancelled" + assert props["$ai_provider"] == provider + assert props["$ai_trace_id"] == "trace-1" + assert "$ai_input_tokens" not in props + assert "$ai_output_tokens" not in props + + +@pytest.mark.asyncio +async def test_provider_error_is_captured_and_reraised(captured_generations): + client, events = captured_generations + error = RuntimeError("provider error") + + async def failing_call(**kwargs): + raise error + + with pytest.raises(RuntimeError) as exc_info: + await call_llm_and_track_usage_async( + None, client, "gemini", None, None, False, None, "", failing_call + ) + + assert exc_info.value is error + assert len(events) == 1 + props = events[0]["properties"] + assert props["$ai_http_status"] == 0 + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "provider error" From 486963c4b580d5d0056d64b49c22ad4caf67618e Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 17:02:16 +0000 Subject: [PATCH 11/70] chore: Release v7.70.2 [skip ci] (cherry picked from commit e3818080b5aa2f7f885b3b99643a7f34f9f9f3d8) --- .sampo/changesets/venerable-baroness-lemminkainen.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/venerable-baroness-lemminkainen.md diff --git a/.sampo/changesets/venerable-baroness-lemminkainen.md b/.sampo/changesets/venerable-baroness-lemminkainen.md deleted file mode 100644 index 5dc5c3502..000000000 --- a/.sampo/changesets/venerable-baroness-lemminkainen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Mark cancelled async LLM calls as errors while preserving cancellation. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index d1e981944..9ec2bd183 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.106 — 2026-10-15 + +### Patch changes + +- Updated dependencies: posthog@7.70.2 + ## 0.1.105 — 2026-10-15 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 52b9920d9..d83fb0c42 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.105" +version = "0.1.106" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 7dbe1ba87..1e1e76b84 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.70.2 — 2026-10-15 + +### Patch changes + +- [fec41f2](https://github.com/posthog/posthog-python/commit/fec41f24cb497d37a8cd0dd53490b74c98554dfa) Mark cancelled async LLM calls as errors while preserving cancellation. — Thanks @marandaneto! + ## 7.70.1 — 2026-10-15 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index b4fa8dd98..c4ce44e4d 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.70.1" +VERSION = "7.70.2" diff --git a/pyproject.toml b/pyproject.toml index 0332a2142..dc640a4ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.70.1" +version = "7.70.2" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index fb55693ce..2ddceb77b 100644 --- a/uv.lock +++ b/uv.lock @@ -2490,7 +2490,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.105" +version = "0.1.106" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2820,7 +2820,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.1" +version = "7.70.2" source = { editable = "." } dependencies = [ { name = "distro" }, From e759542aff3d537c1a1d4f2efcac306e543c3564 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 15 Oct 2026 17:02:22 +0000 Subject: [PATCH 12/70] Update generated references (cherry picked from commit f33d55d0f1fd01698140cff73e21b9f65bd1f0d7) --- .../posthog-python-references-7.70.2.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.70.2.json diff --git a/references/posthog-python-references-7.70.2.json b/references/posthog-python-references-7.70.2.json new file mode 100644 index 000000000..598946836 --- /dev/null +++ b/references/posthog-python-references-7.70.2.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.70.2", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely. Queued spans are sent at the same time, within the same", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name')\nposthog.flush() # Ensures the event is sent immediately" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Queued spans get one final flush of up to 30 s (plus a request already in flight); any it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Tell the client to flush all queued events.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import flush\nflush()" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Flush all messages and cleanly shutdown the client. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index affb9655a..598946836 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.70.1", + "version": "7.70.2", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From f466072962d2b97f5ddd4a2ba0e684ae7a4c30da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 17:45:53 +0000 Subject: [PATCH 13/70] chore(deps): bump the ai-providers group with 8 updates (#1054) Bumps the ai-providers group with 8 updates: | Package | From | To | | --- | --- | --- | | [langchain](https://github.com/langchain-ai/langchain) | `1.4.2` | `1.4.3` | | [anthropic](https://github.com/anthropics/anthropic-sdk-python) | `1.8.0` | `1.11.0` | | [langgraph](https://github.com/langchain-ai/langgraph) | `1.2.12` | `1.2.13` | | [langchain-core](https://github.com/langchain-ai/langchain) | `1.6.5` | `1.6.6` | | [langchain-openai](https://github.com/langchain-ai/langchain) | `1.6.6` | `1.6.7` | | [langchain-anthropic](https://github.com/langchain-ai/langchain) | `1.7.4` | `1.7.5` | | [google-genai](https://github.com/googleapis/python-genai) | `2.25.0` | `2.28.0` | | [langchain-text-splitters](https://github.com/langchain-ai/langchain) | `1.1.2` | `1.1.3` | Updates `langchain` from 1.4.2 to 1.4.3 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain==1.4.2...langchain==1.4.3) Updates `anthropic` from 1.8.0 to 1.11.0 - [Release notes](https://github.com/anthropics/anthropic-sdk-python/releases) - [Changelog](https://github.com/anthropics/anthropic-sdk-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/anthropics/anthropic-sdk-python/compare/v1.8.0...v1.11.0) Updates `langgraph` from 1.2.12 to 1.2.13 - [Release notes](https://github.com/langchain-ai/langgraph/releases) - [Commits](https://github.com/langchain-ai/langgraph/compare/1.2.12...1.2.13) Updates `langchain-core` from 1.6.5 to 1.6.6 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-core==1.6.5...langchain-core==1.6.6) Updates `langchain-openai` from 1.6.6 to 1.6.7 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-openai==1.6.6...langchain-openai==1.6.7) Updates `langchain-anthropic` from 1.7.4 to 1.7.5 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-anthropic==1.7.4...langchain-anthropic==1.7.5) Updates `google-genai` from 2.25.0 to 2.28.0 - [Release notes](https://github.com/googleapis/python-genai/releases) - [Changelog](https://github.com/googleapis/python-genai/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/python-genai/compare/v2.25.0...v2.28.0) Updates `langchain-text-splitters` from 1.1.2 to 1.1.3 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-text-splitters==1.1.2...langchain-text-splitters==1.1.3) --- updated-dependencies: - dependency-name: langchain dependency-version: 1.4.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: anthropic dependency-version: 1.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ai-providers - dependency-name: langgraph dependency-version: 1.2.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: langchain-core dependency-version: 1.6.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: langchain-openai dependency-version: 1.6.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: langchain-anthropic dependency-version: 1.7.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: google-genai dependency-version: 2.28.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ai-providers - dependency-name: langchain-text-splitters dependency-version: 1.1.3 dependency-type: indirect update-type: version-update:semver-patch dependency-group: ai-providers ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dustin Byrne (cherry picked from commit f95e1f46ef4de0b6903750583f3d63843a6dd685) --- uv.lock | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/uv.lock b/uv.lock index 2ddceb77b..3940fd00a 100644 --- a/uv.lock +++ b/uv.lock @@ -226,7 +226,7 @@ wheels = [ [[package]] name = "anthropic" -version = "1.8.0" +version = "1.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -237,9 +237,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/65/b8/f4de0e90bbd641e86a1d6b20e017442033a2c1d2f5381799f82057115bd7/anthropic-1.8.0.tar.gz", hash = "sha256:9c1783ed90f409617749a61c5ab98e20624a572626f2e0a15cea03ed8e1401e5", size = 1221762, upload-time = "2026-09-22T16:25:38.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/12/9a6ffa397b172adb040008d934a1dfd85d0e4cefc77489416db294ffc880/anthropic-1.11.0.tar.gz", hash = "sha256:3906fabac7ad7b5b46c6186040398fc7826885c77ce34e4dd7849de16fc8d0f8", size = 1390390, upload-time = "2026-09-30T22:58:21.098Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/18/5d25a703b66ba34e9277f875f692a3bea3b0ff4d47ee5d188521a01cdd2a/anthropic-1.8.0-py3-none-any.whl", hash = "sha256:79a4516a21e64fd7b15be1a49ebf544bd6376c96a971a77365358823a2717bc6", size = 1348276, upload-time = "2026-09-22T16:25:36.515Z" }, + { url = "https://files.pythonhosted.org/packages/ab/6f/20edcd2956cac68042b1bcdd13ab3311447519f86b26929ff268dc74c650/anthropic-1.11.0-py3-none-any.whl", hash = "sha256:52f97b2c485cca7ac66058374f5073a3febb7e6849b16989c145d602a3efee21", size = 1681654, upload-time = "2026-09-30T22:58:22.925Z" }, ] [[package]] @@ -1137,7 +1137,7 @@ requests = [ [[package]] name = "google-genai" -version = "2.25.0" +version = "2.28.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1151,9 +1151,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/0a/a3b7856ca840031d4393dbdd97b67fe811b20061315ed68b67b5c85ca80d/google_genai-2.25.0.tar.gz", hash = "sha256:ab603baa5eee0205926ad0f8d7f93e0400df6d67650e99c33e01ab228ea16ad6", size = 699564, upload-time = "2026-09-22T17:23:01.238Z" } +sdist = { url = "https://files.pythonhosted.org/packages/59/16/4af15d65cb72ebc21a99c5e64f09072e97334c05a48d4cede19c347e6ad2/google_genai-2.28.0.tar.gz", hash = "sha256:970cb2eaf1951949851c3e0a5b70265cfea8a408fb7361c7c980a84d90672bf2", size = 707359, upload-time = "2026-10-02T17:58:14.454Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/a8/178dbb9d1d6cac721b01592e291146a024bae5ee3224e36569348921dd6c/google_genai-2.25.0-py3-none-any.whl", hash = "sha256:2e8f3a5f76ed00d5ffc3153f6089bc7d3511054eed53ad9cfc6095a7dc59b028", size = 1159631, upload-time = "2026-09-22T17:22:59.291Z" }, + { url = "https://files.pythonhosted.org/packages/ad/4b/47278c34757293ba8d9156090d38e1c45fac9a47c50176acff7f77ae9a66/google_genai-2.28.0-py3-none-any.whl", hash = "sha256:cdee15e2fbfea08ea61bce6e5bfbb3301db4bd13a52dccfa8c8d1167e37ca1cc", size = 1168554, upload-time = "2026-10-02T17:58:12.585Z" }, ] [[package]] @@ -1631,30 +1631,30 @@ wheels = [ [[package]] name = "langchain" -version = "1.4.2" +version = "1.4.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "langgraph" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ff/670036674e669b81c0ddba77e1f012c099eda7b7d1251b973e5367d2824e/langchain-1.4.2.tar.gz", hash = "sha256:5b476418cacbfb8f0da6e63b3b263eefdcec13b48abd6117565a25728ec10b77", size = 735715, upload-time = "2026-09-18T17:31:11.42Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/aa/0fcaf5d7dbebcf7d0eb74293dca5aee6f0558242731f4dee4a800cc2431d/langchain-1.4.3.tar.gz", hash = "sha256:aed5c1a7cd581f70ddc076b75fdbcbae8031b8373983f86efd287aa70798abc2", size = 738607, upload-time = "2026-09-28T20:17:24.38Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/86/cc13651cfda820d96ca8c612538166334935e8cf4331a31f5dd369d27760/langchain-1.4.2-py3-none-any.whl", hash = "sha256:30a27c34cfa0004bf659dcdef488b99a9b90acb08bcc514a5a74264755da536c", size = 163740, upload-time = "2026-09-18T17:31:10.056Z" }, + { url = "https://files.pythonhosted.org/packages/30/03/8cc027f9d297473de94f134546dae2bfca255161ebbda988522fc509e1d5/langchain-1.4.3-py3-none-any.whl", hash = "sha256:0334066939dd1c7551889727ed2d09a72dea7a6aed2193ffb61817fb658d8921", size = 164708, upload-time = "2026-09-28T20:17:22.978Z" }, ] [[package]] name = "langchain-anthropic" -version = "1.7.4" +version = "1.7.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anthropic" }, { name = "langchain-core" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/b1a7e19a4f129f567f04534e263e14e350673fb35ba5e45b2a189c07d85b/langchain_anthropic-1.7.4.tar.gz", hash = "sha256:7d540300665a1c906986e505cdec41204e759f14dbd989f53f0c180d82624b94", size = 760340, upload-time = "2026-09-23T17:55:49.262Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/e6/45ead93ef6d9f244b502a6a32bf9a185b3da1cc7fa8003896a102dadac09/langchain_anthropic-1.7.5.tar.gz", hash = "sha256:6016f38e5c4bf12c16ecfa76abf133a978f459f4d2887b8e28435ae1ff00beb3", size = 764625, upload-time = "2026-09-29T15:22:07.106Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/2c/d0389b1d8d4a93eadaa9cda07ef7614c0bbfec71f69997d42c32dabbbefa/langchain_anthropic-1.7.4-py3-none-any.whl", hash = "sha256:eec1178389358eaa4cff4f3dd353f063746b8c61090cffe9236d9035df71e66c", size = 63854, upload-time = "2026-09-23T17:55:48.137Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a8/c507f2c1859b584843983e98bc71e0066c16a77e6c181921c928e0fdbcf7/langchain_anthropic-1.7.5-py3-none-any.whl", hash = "sha256:b21ef0e0c2d6175235a5b7eef4f5f89057df92d42dbfab66920a05605ef7173a", size = 65239, upload-time = "2026-09-29T15:22:05.832Z" }, ] [[package]] @@ -1701,7 +1701,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "1.6.5" +version = "1.6.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -1715,14 +1715,14 @@ dependencies = [ { name = "typing-extensions" }, { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/ed/ceecd3bfcfc77a94cf30a9f1506e907fdea447458825e01914a72d2d1a6f/langchain_core-1.6.5.tar.gz", hash = "sha256:bdb059fef65473fd444558dbb18f50901657402c43ceed9dc0fdc7b76a393c6b", size = 1007041, upload-time = "2026-09-24T18:11:06.487Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/9e5d393bbcec068c51becc255a15aacfd8a14ac5826179751c1c320e5258/langchain_core-1.6.6.tar.gz", hash = "sha256:67616d984c085009be2c381c2efd330d32429a58aebab295b4f51b6573964511", size = 1007227, upload-time = "2026-09-29T14:52:54.598Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/68/447ac7e734990b7ed9dcfc3b6dee9a4cd4d4169e296429fa71a9a47c1c7b/langchain_core-1.6.5-py3-none-any.whl", hash = "sha256:54c7b0e9314b9084fb04405bb33dc5d32986d512d92b7b8863899cd5f6267556", size = 572136, upload-time = "2026-09-24T18:11:04.837Z" }, + { url = "https://files.pythonhosted.org/packages/90/10/8c00b4dc094886314c907ec7ead258dfee28948cf44175976cc4fba9aba8/langchain_core-1.6.6-py3-none-any.whl", hash = "sha256:d9a71e312ab7443701238750e04a57aefc037c4f1ec82837c8a1609d9a14a9b1", size = 572080, upload-time = "2026-09-29T14:52:53.213Z" }, ] [[package]] name = "langchain-openai" -version = "1.6.6" +version = "1.6.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1730,9 +1730,9 @@ dependencies = [ { name = "openai" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/14/6d9c4d07b43c1eaf8a112be3524b951247c44bb195d6224cab8ffb68b3e8/langchain_openai-1.6.6.tar.gz", hash = "sha256:7b3848f42825aca40165463aa37757051165eb292ba7f24658a2f58f9bb221f9", size = 3306663, upload-time = "2026-09-24T11:31:13.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2f/367068190b5a7d181996ad7899052394f0276468c92be48e0b7dab63716a/langchain_openai-1.6.7.tar.gz", hash = "sha256:b276a01b43c5287382f62070a4e1ca5bad5581fadab8c086e46b79daa4bf975d", size = 3380633, upload-time = "2026-09-30T15:12:03.1Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/c6/0f6b0c9faa7d00eef702c133fd3534cb52cbdf56df9f3524666012ec90e0/langchain_openai-1.6.6-py3-none-any.whl", hash = "sha256:60dcaa443ddfdf1559feaf1d25916f394c7dda809aebe22a769fc39f02705be7", size = 127401, upload-time = "2026-09-24T11:31:11.691Z" }, + { url = "https://files.pythonhosted.org/packages/18/d9/b3db61c6c15766c999194a9cba0b9c5035567b7e0dd1c1a94a6d76448cd6/langchain_openai-1.6.7-py3-none-any.whl", hash = "sha256:e1b9b318fafc47b2dbc3485778aa23f809195065ee313611c188af29744b8e8e", size = 127883, upload-time = "2026-09-30T15:12:01.876Z" }, ] [[package]] @@ -1749,19 +1749,19 @@ wheels = [ [[package]] name = "langchain-text-splitters" -version = "1.1.2" +version = "1.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/26/9f/6c545900fefb7b00ddfa3f16b80d61338a0ec68c31c5451eeeab99082760/langchain_text_splitters-1.1.2.tar.gz", hash = "sha256:782a723db0a4746ac91e251c7c1d57fd23636e4f38ed733074e28d7a86f41627", size = 293580, upload-time = "2026-04-16T14:20:39.162Z" } +sdist = { url = "https://files.pythonhosted.org/packages/85/22/d401fffe8d3f1339f6ac880e5d637db73933efa95635304849b2d44ab0fe/langchain_text_splitters-1.1.3.tar.gz", hash = "sha256:929b6c76f99d611a5b1d8f5591ef302909b86a436ceb3217034d24e4757868d8", size = 308295, upload-time = "2026-10-02T15:46:33.173Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/26/1ef06f56198d631296d646a6223de35bcc6cf9795ceb2442816bc963b84c/langchain_text_splitters-1.1.2-py3-none-any.whl", hash = "sha256:a2de0d799ff31886429fd6e2e0032df275b60ec817c19059a7b46181cc1c2f10", size = 35903, upload-time = "2026-04-16T14:20:38.243Z" }, + { url = "https://files.pythonhosted.org/packages/c7/51/2880d2e88cce13c1180178f7e8dc796c2f45b2dc09cc09ed407d116c08cc/langchain_text_splitters-1.1.3-py3-none-any.whl", hash = "sha256:50edeb318b3be6a6308dddd7d616ab82823a9ccbea59a9c14c58a7b91df60295", size = 38217, upload-time = "2026-10-02T15:46:32.271Z" }, ] [[package]] name = "langgraph" -version = "1.2.12" +version = "1.2.13" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, @@ -1771,9 +1771,9 @@ dependencies = [ { name = "pydantic" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/7e/c9e4431adb5eb78d15f0035aae162a113c80d037ceb433ddd78835217848/langgraph-1.2.12.tar.gz", hash = "sha256:5fae9fa4ce771e90f10ff19ce0d5aaef4b41d7632c713d769e89cbce1241a4b9", size = 734541, upload-time = "2026-09-21T14:43:29.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/22/75ab5e7d13c842d8dc68f115cf6cc5a651a8d5a993e72a621c98bfb2b1cd/langgraph-1.2.13.tar.gz", hash = "sha256:a3cae71d4cb88455d7a8887109665525aefe4ab13fe941d653cd4b6de2af45c6", size = 752793, upload-time = "2026-10-05T17:51:21.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/27/5a02054c535ed6fcfb2ab1e5c33c51c810cf1e773194ad28c928f0473509/langgraph-1.2.12-py3-none-any.whl", hash = "sha256:95403af7b510de8d79164742f71daaf866c69ca804a8cb72bef2cc1fa1ab9813", size = 250206, upload-time = "2026-09-21T14:43:28.196Z" }, + { url = "https://files.pythonhosted.org/packages/da/8e/b7471af7fc72c218e545c74454c386a4b0867a8a15c9893db1d28464f492/langgraph-1.2.13-py3-none-any.whl", hash = "sha256:5d45a021e043aaf39f32122e620eacfd1245aa84dfaa84b0814cef0f4ac78eb4", size = 255979, upload-time = "2026-10-05T17:51:20.221Z" }, ] [[package]] From 355fe02bc148bf38c1637265dc05ad03a9de9f31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 17:46:19 +0000 Subject: [PATCH 14/70] chore(deps): bump the github-actions group with 2 updates (#1055) Bumps the github-actions group with 2 updates: [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) and [PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml](https://github.com/posthog/posthog-sdk-test-harness). Updates `dtolnay/rust-toolchain` from 7e38f4b43b4db5c8dd498af069a4f6196df1d067 to e2a55d2ffb04f378e9626c28d38b36d230d1e12f - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/7e38f4b43b4db5c8dd498af069a4f6196df1d067...e2a55d2ffb04f378e9626c28d38b36d230d1e12f) Updates `PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml` from 1.11.0 to 1.13.1 - [Release notes](https://github.com/posthog/posthog-sdk-test-harness/releases) - [Changelog](https://github.com/PostHog/posthog-sdk-test-harness/blob/main/CHANGELOG.md) - [Commits](https://github.com/posthog/posthog-sdk-test-harness/compare/4593de8b423f61fa222115da592e5c18dc82ad3c...e32f08bd30fab57ce543da5808a668d0fda697b0) --- updated-dependencies: - dependency-name: dtolnay/rust-toolchain dependency-version: e2a55d2ffb04f378e9626c28d38b36d230d1e12f dependency-type: direct:production dependency-group: github-actions - dependency-name: PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml dependency-version: 1.13.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dustin Byrne (cherry picked from commit 9b7e63290109c1c5ccdbe5c5225cb07c77e97f73) --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7a360cbd4..6987f2f53 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -107,7 +107,7 @@ jobs: enable-cache: true - name: Install Rust - uses: dtolnay/rust-toolchain@7e38f4b43b4db5c8dd498af069a4f6196df1d067 + uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with: toolchain: 1.91.1 components: cargo @@ -479,7 +479,7 @@ jobs: enable-cache: true - name: Install Rust - uses: dtolnay/rust-toolchain@7e38f4b43b4db5c8dd498af069a4f6196df1d067 + uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f with: toolchain: 1.91.1 components: cargo From 764a48589f4672fa5dc703f76b712124bf114b53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 11:13:16 -0700 Subject: [PATCH 15/70] chore(deps): bump mcp from 1.28.1 to 1.30.0 (#1068) Bumps [mcp](https://github.com/modelcontextprotocol/python-sdk) from 1.28.1 to 1.30.0. - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.30.0) --- updated-dependencies: - dependency-name: mcp dependency-version: 1.30.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 12e88a254e900e71824aa9fdc95987ec7082c312) --- uv.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/uv.lock b/uv.lock index 3940fd00a..8e347e10d 100644 --- a/uv.lock +++ b/uv.lock @@ -2068,7 +2068,7 @@ wheels = [ [[package]] name = "mcp" -version = "1.28.1" +version = "1.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -2086,9 +2086,9 @@ dependencies = [ { name = "typing-inspection" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/77/9450b8f251a13affb6281997d0523c4615f8a8b35d0b21ff30db3a5aac9d/mcp-1.28.1.tar.gz", hash = "sha256:d51e36a5f5644faea4f85ea649bfffa6bc6c26770d42798ad6a3de3d2ba69683", size = 638501, upload-time = "2026-06-26T12:57:29.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/93/0142dc84a666daf8ad51a34268f34c12fd6fda4f3810c4be2504eecc8212/mcp-1.30.0.tar.gz", hash = "sha256:445414625fce5c295faa505bb11bacece661ab6f4028d57c935db57820b7a3e4", size = 680511, upload-time = "2026-09-07T14:34:15.845Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/5e/d118fce19f87a2e7d8101c35c8ae0ec289098a4df0ff244cec23e415aca0/mcp-1.28.1-py3-none-any.whl", hash = "sha256:2726bca5e7193f61c5dde8b12500a6de2d9acf6d1a1c0be9e8c2e706437991df", size = 222620, upload-time = "2026-06-26T12:57:27.218Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f4/e58bc33317c92a0203664daaf00bf6f41166cc0149e5d6870a03f7cd004a/mcp-1.30.0-py3-none-any.whl", hash = "sha256:666edb5009503e1047c9d60346a756f94b261f05cc2625f23d41c728ffc484d0", size = 234581, upload-time = "2026-09-07T14:34:14.266Z" }, ] [[package]] From 2a11bd276cab29bf90a235f8b381fdd3176a7010 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Date: Sat, 17 Oct 2026 02:21:48 +0700 Subject: [PATCH 16/70] docs: clarify reusable flush and terminal shutdown guidance (#1043) * docs: clarify reusable flush and terminal shutdown guidance * docs: preserve published 7.67.0 reference snapshot (cherry picked from commit d0b6f7127f6d60a17d1c67724ad5eb50d12a7dd6) --- .../flush-shutdown-lifetime-guidance.md | 5 ++ posthog/__init__.py | 47 ++++++++++++--- posthog/client.py | 60 +++++++++++++------ .../posthog-python-references-latest.json | 16 ++--- 4 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 .sampo/changesets/flush-shutdown-lifetime-guidance.md diff --git a/.sampo/changesets/flush-shutdown-lifetime-guidance.md b/.sampo/changesets/flush-shutdown-lifetime-guidance.md new file mode 100644 index 000000000..a87fd12bf --- /dev/null +++ b/.sampo/changesets/flush-shutdown-lifetime-guidance.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Clarify when to flush reusable clients versus shut down disposable clients, including timeout and delivery limitations. diff --git a/posthog/__init__.py b/posthog/__init__.py index 5bea3f82f..4b663db29 100644 --- a/posthog/__init__.py +++ b/posthog/__init__.py @@ -1295,16 +1295,39 @@ def load_feature_flags(): def flush(timeout_seconds: Optional[float] = 10) -> None: """ - Tell the client to flush all queued events. + Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. + + Call ``flush()`` before a short-lived request or serverless invocation returns + when using the shared module-level client. Use ``shutdown()`` only for final + process cleanup or a client that will not be reused. Flush does not stop the + background workers or feature flag poller, and does not end open spans. + + Returning does not guarantee server receipt: pending work can remain after a + timeout or span export failure, and failed events may be dropped by consumers. + Calls made directly from SDK callbacks such as ``on_error`` are deferred + rather than blocking the worker that invoked the callback. Args: - timeout_seconds: Maximum seconds to wait for the queue to flush. - Defaults to 10 seconds. Pass ``None`` to wait indefinitely. + timeout_seconds: Seconds to wait for event queues to drain, shared across + event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a + time limit; this does not guarantee successful delivery. Queued spans + flush concurrently, waiting up to this many seconds for an in-flight + flush before starting a fresh drain budget. A lock wait timeout leaves + the in-flight flush to finish. At least one span request is attempted + after acquiring the lock, even with no budget left; retriable failures + are retried after backoff while budget remains, with one last attempt + at the deadline. The last span request is not cut short and is bounded + by the client's ``timeout`` in seconds, + so this is not a strict wall-clock limit for the whole call. With + ``None``, a retriable span failure is left for a later flush rather than + retried within this call. Examples: ```python - from posthog import flush - flush() + import posthog + posthog.capture('event_name', distinct_id='user_id') + # Before a serverless invocation returns; keep the global client open. + posthog.flush(timeout_seconds=10) ``` Category: @@ -1412,11 +1435,21 @@ def get_active_span() -> Optional[Span]: def shutdown() -> None: """ - Flush all messages and cleanly shutdown the client. + Attempt final delivery and permanently shut down the global client. + + Call this for final process cleanup, not at the end of each request or + serverless invocation that shares the module-level client. Use ``flush()`` + before returning from those invocations instead. Shutdown closes capture + lanes, stops background workers and the feature flag poller, and tears down + integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through - logging or ``on_error``; returning does not guarantee server receipt. + logging or ``on_error``; returning does not guarantee server receipt. Event + draining has no timeout. Queued spans get a final flush with up to 30 seconds + waiting for an in-flight flush, then a fresh 30-second drain budget; the last + HTTP request is not cut short. Unsent queued spans and still-open spans are + discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned diff --git a/posthog/client.py b/posthog/client.py index 34db581d9..557d708b2 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -2878,25 +2878,41 @@ def get_active_span(self) -> Optional[Span]: def flush(self, timeout_seconds: Optional[float] = 10) -> None: """ - Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead. + Attempt immediate delivery of queued events and ended spans, keeping the client reusable. + + For a client shared across requests or serverless invocations (including + the module-level client), call ``flush()`` before a short-lived invocation + returns. Use ``shutdown()`` instead only for final process cleanup or when + disposing of a client that will not be reused. Flush does not stop the + background workers or feature flag poller, and does not end open spans. + + Returning does not guarantee server receipt: pending work can remain after + a timeout or span export failure, and failed events may be dropped by the + consumers. Calls made directly from SDK callbacks such as ``on_error`` are + deferred rather than blocking the worker that invoked the callback. Args: - timeout_seconds: Maximum seconds to wait for the queue to flush. - Defaults to 10 seconds. Pass ``None`` to wait indefinitely. - Queued spans are sent at the same time, within the same - budget: at least one span request is attempted even when the - budget is already spent, a retriable failure is retried after - its backoff while budget remains, no other request starts once - it is spent, and each request is bounded by ``timeout``. The - wait for the last request is not cut short, so a flush can - take up to ``timeout_seconds`` plus ``timeout`` in the worst - case. A span flush already in flight for the whole wait is - left to finish instead. + timeout_seconds: Seconds to wait for event queues to drain, shared + across event lanes. Defaults to 10 seconds. Pass ``None`` to wait + without a time limit; this does not guarantee successful delivery. + Queued spans flush concurrently. The span exporter waits up to + this many seconds for an in-flight flush, then uses a fresh drain + budget once it acquires the lock. If the lock wait times out, the + in-flight flush is left to finish. At least one span request is + attempted after acquiring the lock, even with no budget left; + retriable failures are retried after backoff while budget remains, + with one last attempt at the deadline. Each span request is + bounded by the client's ``timeout`` in + seconds, and the last request is not cut short. This is therefore + not a strict wall-clock limit for the whole call. With ``None``, + a retriable span failure is left for a later flush rather than + retried within this call. Examples: ```python - posthog.capture('event_name') - posthog.flush() # Ensures the event is sent immediately + posthog.capture('event_name', distinct_id='user_id') + # Before a serverless invocation returns; keep the shared client open. + posthog.flush(timeout_seconds=10) ``` """ if self._defer_flush_from_callback(timeout_seconds): @@ -3323,14 +3339,22 @@ def join(self) -> None: @no_throw() def shutdown(self) -> None: """ - Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. + Attempt final delivery and permanently shut down the client. + + Call this for final process cleanup or when disposing of a client that + will not be reused. It closes capture lanes, stops background workers and + the feature flag poller, and tears down integrations. Do not call it at the + end of each request or serverless invocation when the client is shared; + call ``flush()`` before returning instead. A shut-down client cannot be + reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee - server receipt. Queued spans get one final flush of up to 30 s (plus a - request already in flight); any it cannot send are discarded with a - warning, as are spans still open. + server receipt. Event draining has no timeout. Queued spans get one final + flush with up to 30 seconds waiting for an in-flight flush, then a fresh + 30-second drain budget; the last HTTP request is not cut short. Any spans + it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 598946836..4e5e75c7c 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -1001,13 +1001,13 @@ { "id": "flush", "title": "flush", - "description": "Force a flush from the internal queue to the server. Do not use directly, call `shutdown()` instead.", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", "details": "", "category": null, "params": [ { "name": "timeout_seconds", - "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely. Queued spans are sent at the same time, within the same", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", "isOptional": true, "type": "float" } @@ -1022,7 +1022,7 @@ { "id": "example_1", "name": "Example 1", - "code": "posthog.capture('event_name')\nposthog.flush() # Ensures the event is sent immediately" + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" } ] }, @@ -2050,7 +2050,7 @@ { "id": "shutdown", "title": "shutdown", - "description": "Flush all messages and cleanly shutdown the client. Call this before the process ends in serverless environments to avoid data loss. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Queued spans get one final flush of up to 30 s (plus a request already in flight); any it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", "details": "", "category": null, "params": [], @@ -2489,13 +2489,13 @@ { "id": "flush", "title": "flush", - "description": "Tell the client to flush all queued events.", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", "details": "", "category": "Client management", "params": [ { "name": "timeout_seconds", - "description": "Maximum seconds to wait for the queue to flush. Defaults to 10 seconds. Pass ``None`` to wait indefinitely.", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", "isOptional": true, "type": "float" } @@ -2510,7 +2510,7 @@ { "id": "example_1", "name": "Example 1", - "code": "from posthog import flush\nflush()" + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" } ] }, @@ -3421,7 +3421,7 @@ { "id": "shutdown", "title": "shutdown", - "description": "Flush all messages and cleanly shutdown the client. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", "details": "", "category": "Client management", "params": [], From c1022fb342fc26d63da3b246997a258377cac7a5 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:23:37 +0000 Subject: [PATCH 17/70] chore: Release v7.71.0 [skip ci] (cherry picked from commit 20a574ec0d723a2228f51d3a1d63b44ecaf343d4) --- .sampo/changesets/doughty-seer-vellamo.md | 5 ----- .sampo/changesets/flush-shutdown-lifetime-guidance.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 10 ++++++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 8 files changed, 21 insertions(+), 15 deletions(-) delete mode 100644 .sampo/changesets/doughty-seer-vellamo.md delete mode 100644 .sampo/changesets/flush-shutdown-lifetime-guidance.md diff --git a/.sampo/changesets/doughty-seer-vellamo.md b/.sampo/changesets/doughty-seer-vellamo.md deleted file mode 100644 index d4f66dab3..000000000 --- a/.sampo/changesets/doughty-seer-vellamo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -Align ASGI, Flask, and Django tracing-header capture with peer SDKs. Add capture_tracing_headers and POSTHOG_MW_CAPTURE_TRACING_HEADERS, enabled by default once an integration is installed. Keep the trust-named options as deprecated aliases, honor explicit opt-outs, and prefer the capture-named option when both are configured. Share header sanitization and request-context attribution across integrations; explicit capture identity and session properties retain precedence. diff --git a/.sampo/changesets/flush-shutdown-lifetime-guidance.md b/.sampo/changesets/flush-shutdown-lifetime-guidance.md deleted file mode 100644 index a87fd12bf..000000000 --- a/.sampo/changesets/flush-shutdown-lifetime-guidance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Clarify when to flush reusable clients versus shut down disposable clients, including timeout and delivery limitations. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 9ec2bd183..0a671dafb 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.107 — 2026-10-16 + +### Patch changes + +- Updated dependencies: posthog@7.71.0 + ## 0.1.106 — 2026-10-15 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index d83fb0c42..36dfc3477 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.106" +version = "0.1.107" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 1e1e76b84..1baddc69b 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,15 @@ # posthog +## 7.71.0 — 2026-10-16 + +### Minor changes + +- [780cba9](https://github.com/posthog/posthog-python/commit/780cba9aeea0d990a65fafe88860905bb4941d81) Align ASGI, Flask, and Django tracing-header capture with peer SDKs. Add capture_tracing_headers and POSTHOG_MW_CAPTURE_TRACING_HEADERS, enabled by default once an integration is installed. Keep the trust-named options as deprecated aliases, honor explicit opt-outs, and prefer the capture-named option when both are configured. Share header sanitization and request-context attribution across integrations; explicit capture identity and session properties retain precedence. — Thanks @dustinbyrne! + +### Patch changes + +- [d0b6f71](https://github.com/posthog/posthog-python/commit/d0b6f7127f6d60a17d1c67724ad5eb50d12a7dd6) Clarify when to flush reusable clients versus shut down disposable clients, including timeout and delivery limitations. — Thanks @marandaneto! + ## 7.70.2 — 2026-10-15 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index c4ce44e4d..08106028b 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.70.2" +VERSION = "7.71.0" diff --git a/pyproject.toml b/pyproject.toml index dc640a4ec..471f5d548 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.70.2" +version = "7.71.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 8e347e10d..c62d47bba 100644 --- a/uv.lock +++ b/uv.lock @@ -2490,7 +2490,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.106" +version = "0.1.107" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2820,7 +2820,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.2" +version = "7.71.0" source = { editable = "." } dependencies = [ { name = "distro" }, From 26f7af922bbe5f7f918aa81f7a1f30b4c46dc017 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:23:43 +0000 Subject: [PATCH 18/70] Update generated references (cherry picked from commit 883eacaba876dfc7d50febbf44b791470df7cc51) --- .../posthog-python-references-7.71.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.71.0.json diff --git a/references/posthog-python-references-7.71.0.json b/references/posthog-python-references-7.71.0.json new file mode 100644 index 000000000..342930ffc --- /dev/null +++ b/references/posthog-python-references-7.71.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.71.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 4e5e75c7c..342930ffc 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.70.2", + "version": "7.71.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From cb05402604d52b917be32e227223e156d486be7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 13:45:35 -0700 Subject: [PATCH 19/70] chore(deps): bump the uv group across 4 directories with 2 updates (#1069) Bumps the uv group with 1 update in the /examples/example-ai-llamaindex directory: [tinytag](https://github.com/tinytag/tinytag). Bumps the uv group with 1 update in the /examples/example-ai-openai-agents directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Bumps the uv group with 1 update in the /examples/example-ai-pydantic-ai directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Bumps the uv group with 1 update in the /examples/example-ai-semantic-kernel directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Updates `tinytag` from 2.2.1 to 2.3.0 - [Release notes](https://github.com/tinytag/tinytag/releases) - [Commits](https://github.com/tinytag/tinytag/compare/2.2.1...2.3.0) Updates `mcp` from 1.28.1 to 1.30.0 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.30.0) Updates `mcp` from 1.29.1 to 1.30.0 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.30.0) Updates `mcp` from 2.1.1 to 2.2.0 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](https://github.com/modelcontextprotocol/python-sdk/compare/v1.28.1...v1.30.0) --- updated-dependencies: - dependency-name: tinytag dependency-version: 2.3.0 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 1.30.0 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 1.30.0 dependency-type: indirect dependency-group: uv - dependency-name: mcp dependency-version: 2.2.0 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit b1363dc5e20c46f6a2c7f33cbf586fd9c302d80b) --- examples/example-ai-llamaindex/uv.lock | 8 ++++---- examples/example-ai-openai-agents/uv.lock | 18 ++++++++--------- examples/example-ai-pydantic-ai/uv.lock | 10 +++++----- examples/example-ai-semantic-kernel/uv.lock | 22 +++++++++++---------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/examples/example-ai-llamaindex/uv.lock b/examples/example-ai-llamaindex/uv.lock index 0068648e4..aaba29e51 100644 --- a/examples/example-ai-llamaindex/uv.lock +++ b/examples/example-ai-llamaindex/uv.lock @@ -1763,7 +1763,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.66.0" +version = "7.70.2" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -2460,11 +2460,11 @@ wheels = [ [[package]] name = "tinytag" -version = "2.2.1" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/59/8a8cb2331e2602b53e4dc06960f57d1387a2b18e7efd24e5f9cb60ea4925/tinytag-2.2.1.tar.gz", hash = "sha256:e6d06610ebe7cd66fd07be2d3b9495914ab32654a5e47657bb8cd44c2484523c", size = 38214, upload-time = "2026-03-15T18:48:01.11Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/a4/a1d39cc10b43cbbae268127a1c38d689bc6a85cf966f9445bc9f1f5f517a/tinytag-2.3.0.tar.gz", hash = "sha256:84850f8045424b944475b9754bc35c7e09bcae1ab08d1f88d9293aa33af39a27", size = 44379, upload-time = "2026-07-30T23:35:03.407Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/34/d50e338631baaf65ec5396e70085e5de0b52b24b28db1ffbc1c6e82190dc/tinytag-2.2.1-py3-none-any.whl", hash = "sha256:ed8b1e6d25367937e3321e054f4974f9abfde1a3e0a538824c87da377130c2b6", size = 32927, upload-time = "2026-03-15T18:47:59.613Z" }, + { url = "https://files.pythonhosted.org/packages/90/48/f9a955e0d27376dd0a6bcf7973818b19e5965dd847580aef2f08c6d6f64b/tinytag-2.3.0-py3-none-any.whl", hash = "sha256:231ba5b2fb7a6db478f6dd344ebf20dfdfcd5907f142d475605d516dd7e8b9a8", size = 37155, upload-time = "2026-07-30T23:35:02.003Z" }, ] [[package]] diff --git a/examples/example-ai-openai-agents/uv.lock b/examples/example-ai-openai-agents/uv.lock index 0a084773f..a2666834f 100644 --- a/examples/example-ai-openai-agents/uv.lock +++ b/examples/example-ai-openai-agents/uv.lock @@ -575,7 +575,7 @@ wheels = [ [[package]] name = "mcp" -version = "1.28.1" +version = "1.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -593,9 +593,9 @@ dependencies = [ { name = "typing-inspection" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/77/9450b8f251a13affb6281997d0523c4615f8a8b35d0b21ff30db3a5aac9d/mcp-1.28.1.tar.gz", hash = "sha256:d51e36a5f5644faea4f85ea649bfffa6bc6c26770d42798ad6a3de3d2ba69683", size = 638501, upload-time = "2026-06-26T12:57:29.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/93/0142dc84a666daf8ad51a34268f34c12fd6fda4f3810c4be2504eecc8212/mcp-1.30.0.tar.gz", hash = "sha256:445414625fce5c295faa505bb11bacece661ab6f4028d57c935db57820b7a3e4", size = 680511, upload-time = "2026-09-07T14:34:15.845Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/5e/d118fce19f87a2e7d8101c35c8ae0ec289098a4df0ff244cec23e415aca0/mcp-1.28.1-py3-none-any.whl", hash = "sha256:2726bca5e7193f61c5dde8b12500a6de2d9acf6d1a1c0be9e8c2e706437991df", size = 222620, upload-time = "2026-06-26T12:57:27.218Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f4/e58bc33317c92a0203664daaf00bf6f41166cc0149e5d6870a03f7cd004a/mcp-1.30.0-py3-none-any.whl", hash = "sha256:666edb5009503e1047c9d60346a756f94b261f05cc2625f23d41c728ffc484d0", size = 234581, upload-time = "2026-09-07T14:34:14.266Z" }, ] [[package]] @@ -882,11 +882,11 @@ crypto = [ [[package]] name = "python-dotenv" -version = "1.2.3" +version = "1.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/53/ed9d74092561d4b01a2ef1349d52cdbc135e526c245f366b089cfca6de49/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35", size = 58945, upload-time = "2026-08-16T16:54:54.067Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/26/2fbeedb218a787a5eea551c7532cac4e009f83d689dd2faa0d0353473f86/python_dotenv-1.2.4.tar.gz", hash = "sha256:f0d53e69935a851c0dcc78f3ab7aaccd8cabef0b92382b576b824212902873c0", size = 60824, upload-time = "2026-10-01T05:36:10Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" }, + { url = "https://files.pythonhosted.org/packages/60/d1/38f3a3405989a89ac18390803e70c6ad7c7760da4f9b83cbeca0c44a0c72/python_dotenv-1.2.4-py3-none-any.whl", hash = "sha256:42269a8a5b3fd54ffa6f3d84b18abed50064717576b4ecf03dc4a55d8aa04fdc", size = 23266, upload-time = "2026-10-01T05:36:08.633Z" }, ] [[package]] @@ -1095,15 +1095,15 @@ wheels = [ [[package]] name = "starlette" -version = "1.6.0" +version = "1.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/b4/205b0d5241d934e8add0c38aa924c4f9fb7330834ff11e5444db964ec3f9/starlette-1.6.0.tar.gz", hash = "sha256:d4e3ac5e546444960c710297a3c9fc3f7ebae1b7e963f3d36173b49da535be9b", size = 2716969, upload-time = "2026-08-08T18:27:57.512Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/2b/3850dc6bf7ef71b088962eba31dafc6cffd2f96e577ebb0bb316df96da3e/starlette-1.7.0.tar.gz", hash = "sha256:c79f74ea63cff761804fbbfb182f1e0b440c2d07b164d24700c5a1bab5d6ff5d", size = 2736246, upload-time = "2026-09-23T07:30:26.35Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/cb/6a6a47d5b464bd08695d254f3da6e7986cc70c9fa5d778eda57538edfe56/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c", size = 75969, upload-time = "2026-08-08T18:27:56.196Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d6/1ec1b290f9e0fb067899b61e1d37a30c923068bad260b216dbe37a7d2967/starlette-1.7.0-py3-none-any.whl", hash = "sha256:67f8e99895493dd2911a03f11314af6ceebeae4e704bb9f43dfc6a9db151c93e", size = 78980, upload-time = "2026-09-23T07:30:24.567Z" }, ] [[package]] diff --git a/examples/example-ai-pydantic-ai/uv.lock b/examples/example-ai-pydantic-ai/uv.lock index 90f37651d..0a303b6ab 100644 --- a/examples/example-ai-pydantic-ai/uv.lock +++ b/examples/example-ai-pydantic-ai/uv.lock @@ -4,8 +4,8 @@ requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", "python_full_version >= '3.14' and sys_platform != 'win32'", - "python_full_version < '3.14' and sys_platform == 'win32'", "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform == 'win32'", "(python_full_version < '3.12' and sys_platform == 'emscripten') or (python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32')", ] @@ -1631,7 +1631,7 @@ wheels = [ [[package]] name = "mcp" -version = "1.29.1" +version = "1.30.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1649,9 +1649,9 @@ dependencies = [ { name = "typing-inspection" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/48/0bb26fdfe7ac16875f534a101ce2405eae192bdef37e7451f2f4507c13ec/mcp-1.29.1.tar.gz", hash = "sha256:1967ba4c315f7a375146209949f45950d18b0efd2f913d7cf3400bc723ee5f04", size = 646823, upload-time = "2026-08-24T18:30:41.161Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/93/0142dc84a666daf8ad51a34268f34c12fd6fda4f3810c4be2504eecc8212/mcp-1.30.0.tar.gz", hash = "sha256:445414625fce5c295faa505bb11bacece661ab6f4028d57c935db57820b7a3e4", size = 680511, upload-time = "2026-09-07T14:34:15.845Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/04/d6b4fb82eefe9e81807aabca1ac98f460ae0883974b83a997aaa20c52545/mcp-1.29.1-py3-none-any.whl", hash = "sha256:b6310eeb59153300c4ab8b9aec4c52f4819a2d6a8e429eb43d908bed7c783648", size = 224653, upload-time = "2026-08-24T18:30:39.573Z" }, + { url = "https://files.pythonhosted.org/packages/f5/f4/e58bc33317c92a0203664daaf00bf6f41166cc0149e5d6870a03f7cd004a/mcp-1.30.0-py3-none-any.whl", hash = "sha256:666edb5009503e1047c9d60346a756f94b261f05cc2625f23d41c728ffc484d0", size = 234581, upload-time = "2026-09-07T14:34:14.266Z" }, ] [[package]] @@ -2066,7 +2066,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.66.0" +version = "7.70.2" source = { directory = "../../" } dependencies = [ { name = "backoff" }, diff --git a/examples/example-ai-semantic-kernel/uv.lock b/examples/example-ai-semantic-kernel/uv.lock index 7ba0cc72f..956aa7a39 100644 --- a/examples/example-ai-semantic-kernel/uv.lock +++ b/examples/example-ai-semantic-kernel/uv.lock @@ -1350,7 +1350,7 @@ wheels = [ [[package]] name = "mcp" -version = "2.1.1" +version = "2.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1368,22 +1368,22 @@ dependencies = [ { name = "typing-inspection" }, { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/6e/21fb8e5d579dbe21d96ea4d5034200d46d8bdf2261053b5bd041f3c2f612/mcp-2.1.1.tar.gz", hash = "sha256:50b7ba1ebbe117008ea7bdd288234043e69c20b403d6851d19661e6d431a75ef", size = 3984589, upload-time = "2026-08-25T16:14:02.376Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/31/ac54fb0fdd5b37de704486e288bba4fbbb463f24cfcfedbede407b854513/mcp-2.2.0.tar.gz", hash = "sha256:2dc37ecb1974becdcebdbf7561e7c15a07dbbf20ba21ba16c3593b3038b3afbd", size = 4084129, upload-time = "2026-09-07T16:06:23.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/af/8644cc5fa26a59afd2df2e98eeb19e72926887fa4b7441aba4ff661140db/mcp-2.1.1-py3-none-any.whl", hash = "sha256:1c6c31c5d6471c58db76af3af8af67f46d11d01f0a59077d0a308cbdb3d3e915", size = 357912, upload-time = "2026-08-25T16:13:59.024Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ff/8e7eade68b8a28f7da0ed1085544341b51f9c935dbf6b95c76b7edfea6a0/mcp-2.2.0-py3-none-any.whl", hash = "sha256:bde982589473a060ae145e3406e9a5333fe538c97229ba841f5a7f92be004f81", size = 365656, upload-time = "2026-09-07T16:06:19.711Z" }, ] [[package]] name = "mcp-types" -version = "2.1.1" +version = "2.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/dd/1c4417dc0b722c23a1669032d5f044e41170fe5d4773b488a50fcce98c32/mcp_types-2.1.1.tar.gz", hash = "sha256:77dcbe48fba73cca71a673f2646a5f037a017b7a0a07ac89cec1113028890eda", size = 66674, upload-time = "2026-08-25T16:14:03.861Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/91/762d7755d971aff8a28d75f7961656148edf27875c8026e6385aaab08ae7/mcp_types-2.2.0.tar.gz", hash = "sha256:d3ed53703ddd10d9c6399f29d322bb66f3f67ab41348ac8556ba23e07fedefad", size = 65892, upload-time = "2026-09-07T16:06:25.187Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/d0/242e63c510f4a17381f55b1549a3f94f5687a0595984febd2b6f87a687a0/mcp_types-2.1.1-py3-none-any.whl", hash = "sha256:26f9f7f03f2a5730717a5b98e2ab7eb640ac352d05a00cdc725c311864778295", size = 69656, upload-time = "2026-08-25T16:14:00.667Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d7/6ffba5d8cd5dd9b8a19478875c50e04945314ba5074e84d749283f27f62d/mcp_types-2.2.0-py3-none-any.whl", hash = "sha256:ea476b73ee86709ab5abc9452385ed36cc05907e582355622e294595c9a04f13", size = 69106, upload-time = "2026-09-07T16:06:21.461Z" }, ] [[package]] @@ -1969,7 +1969,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.63.0" +version = "7.70.2" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -1993,7 +1993,9 @@ requires-dist = [ { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -2426,11 +2428,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.2.3" +version = "1.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/53/ed9d74092561d4b01a2ef1349d52cdbc135e526c245f366b089cfca6de49/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35", size = 58945, upload-time = "2026-08-16T16:54:54.067Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/26/2fbeedb218a787a5eea551c7532cac4e009f83d689dd2faa0d0353473f86/python_dotenv-1.2.4.tar.gz", hash = "sha256:f0d53e69935a851c0dcc78f3ab7aaccd8cabef0b92382b576b824212902873c0", size = 60824, upload-time = "2026-10-01T05:36:10Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" }, + { url = "https://files.pythonhosted.org/packages/60/d1/38f3a3405989a89ac18390803e70c6ad7c7760da4f9b83cbeca0c44a0c72/python_dotenv-1.2.4-py3-none-any.whl", hash = "sha256:42269a8a5b3fd54ffa6f3d84b18abed50064717576b4ecf03dc4a55d8aa04fdc", size = 23266, upload-time = "2026-10-01T05:36:08.633Z" }, ] [[package]] From 5a89eb0307bb3a617e1ffbae23927c57af02872a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 14:00:38 -0700 Subject: [PATCH 20/70] chore(deps-dev): bump claude-agent-sdk from 0.1.50 to 0.2.121 (#1073) Bumps [claude-agent-sdk](https://github.com/anthropics/claude-agent-sdk-python) from 0.1.50 to 0.2.121. - [Release notes](https://github.com/anthropics/claude-agent-sdk-python/releases) - [Changelog](https://github.com/anthropics/claude-agent-sdk-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/anthropics/claude-agent-sdk-python/compare/v0.1.50...v0.2.121) --- updated-dependencies: - dependency-name: claude-agent-sdk dependency-version: 0.2.121 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit a89acf807c35a780545c1327530c97c8c1b0a008) --- uv.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/uv.lock b/uv.lock index c62d47bba..e7fbd5d88 100644 --- a/uv.lock +++ b/uv.lock @@ -584,20 +584,21 @@ wheels = [ [[package]] name = "claude-agent-sdk" -version = "0.1.50" +version = "0.2.121" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "mcp" }, + { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/24/eb/42a7027a02d3827c6e49f97375a00e6da4708f81295d9afa1a0009ce4abd/claude_agent_sdk-0.1.50.tar.gz", hash = "sha256:e15157792857ecb55274a71f08981efcfda2e169bee7894cbdc245d05ac43203", size = 99070, upload-time = "2026-03-20T23:00:58.646Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/9a/7b176b2afef7e4b671bf3723c2a3b09f912ee071e06c15f7f09c46d30ca2/claude_agent_sdk-0.2.121.tar.gz", hash = "sha256:a00f313ebbbf9a7756ec8734c9e9c3c11c53bd56b144dcbd35d4b1bc54fa1d08", size = 297004, upload-time = "2026-07-17T00:38:20.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/97/66bc98d5026dbed68b7469a4990de71d8c40d19713e37dafacf32ba3be3b/claude_agent_sdk-0.1.50-py3-none-macosx_11_0_arm64.whl", hash = "sha256:858b1822451209b2c3ad8df27458168d29ac19fd628680853f7707ea017fea73", size = 58223299, upload-time = "2026-03-20T23:01:01.742Z" }, - { url = "https://files.pythonhosted.org/packages/35/0d/65dda40016faa30a63a950d48b400ad26913e8e333e418651faf04d20673/claude_agent_sdk-0.1.50-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:44e75b9d076bd6030742729f99eb38777b80f052b22338d0a028d8190fc59e52", size = 61019645, upload-time = "2026-03-20T23:01:04.742Z" }, - { url = "https://files.pythonhosted.org/packages/ec/c0/e5c7c6b9e378553fe24bb5367caede725e274a494b6d126e719971c53b8b/claude_agent_sdk-0.1.50-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:7363d431dc6efd83fa658a045e14fa4357440352b548002bfb9096d8f04d143c", size = 74590847, upload-time = "2026-03-20T23:01:07.899Z" }, - { url = "https://files.pythonhosted.org/packages/3d/af/658a28cb070e0b59ac98e88411536f6f9b8d81e8ddde9a8340106b0b8b0f/claude_agent_sdk-0.1.50-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:493d8cc43f4166291606749cf47b03e822f03b7f371cc77af697564017ccf579", size = 75231505, upload-time = "2026-03-20T23:01:11.45Z" }, - { url = "https://files.pythonhosted.org/packages/41/44/ff1f2c137406392fa0a69e3c3ff37150267da664decddb6dee83b80ba162/claude_agent_sdk-0.1.50-py3-none-win_amd64.whl", hash = "sha256:2e44caf3e5bce56e26a18158acf3e1c2c2784cf8fa15e425afe92816c987eb1a", size = 75846174, upload-time = "2026-03-20T23:01:15.277Z" }, + { url = "https://files.pythonhosted.org/packages/ca/3b/16325094d09ca5fbfb92cab11c6f01ff072f4077879ecfcf0004464da3c5/claude_agent_sdk-0.2.121-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6d4707c4626434e75c35f350e66312d8447221c97208f1775d4b4c6542b8d2f2", size = 71735241, upload-time = "2026-07-17T00:38:23.74Z" }, + { url = "https://files.pythonhosted.org/packages/53/d8/cfcd5ea965e0e54cdab58d74d01580489eb5cc02c331e1d2577083b12c06/claude_agent_sdk-0.2.121-py3-none-macosx_11_0_x86_64.whl", hash = "sha256:9c58d83ae9feacc3f06038d86c403e3785a166ef27ae5ae52842864c9a72b90f", size = 76705265, upload-time = "2026-07-17T00:38:27.559Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6d/304282a3e73fa528621508fc205f608c48ca679b176a7ba7003e7e4bcf25/claude_agent_sdk-0.2.121-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:e5b788269f731e73b89785415010fa750ddcf0f35eb9bb4a20bc64e9f52356b4", size = 81636213, upload-time = "2026-07-17T00:38:31.038Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a8/b08d07d090bf07bd84a4243f98813b1c2bea6dc310aa58a7581f216ee89f/claude_agent_sdk-0.2.121-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:65ccbb1bbeed53d8bc60e87a1d46b903b8ba5636a6b300eaa0d284035f844ece", size = 82695285, upload-time = "2026-07-17T00:38:35.198Z" }, + { url = "https://files.pythonhosted.org/packages/e0/69/af814cc15b00ce97132714052a5b3374151d2697fb559600c6187853f327/claude_agent_sdk-0.2.121-py3-none-win_amd64.whl", hash = "sha256:aa34c094aa9278823d64292db0a624bf1dadb800bcc769a96742393fcf01fb9f", size = 82562260, upload-time = "2026-07-17T00:38:38.674Z" }, ] [[package]] From 19a366019bd857c4130d698061d5033d6bbbac33 Mon Sep 17 00:00:00 2001 From: Georgis Andonis <6430745+gesh@users.noreply.github.com> Date: Mon, 19 Oct 2026 12:08:09 +0300 Subject: [PATCH 21/70] feat(mcp): stop sending standalone $identify events (#1067) * feat(mcp): stop sending standalone $identify events The identify callback still sets distinct_id, $set and $groups on every event. The standalone event carried no $anon_distinct_id, so ingestion merged no person, and stateless servers sent one per tool call. Co-Authored-By: Claude Opus 5.5 * chore(mcp): assert no $identify over the wire and refresh docs Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 (cherry picked from commit facd617491a74d8c3c751f0a628661b3817b250d) --- .sampo/changesets/quiet-mcp-identify.md | 5 ++ examples/mcp_analytics_demo.py | 2 +- posthog/mcp/_event_types.py | 1 - posthog/mcp/_instrumentation.py | 10 ++- posthog/mcp/_internal.py | 85 +++-------------------- posthog/mcp/_posthog_events.py | 1 - posthog/mcp/constants.py | 1 + posthog/test/mcp/test_fastmcp.py | 3 +- posthog/test/mcp/test_lowlevel.py | 16 ++--- posthog/test/mcp/test_pipeline.py | 5 -- posthog/test/mcp/test_units.py | 8 --- posthog/test/mcp/test_v2_mcpserver.py | 16 +---- posthog/test/mcp/test_v2_wire_dual_era.py | 45 +++++++++++- 13 files changed, 73 insertions(+), 125 deletions(-) create mode 100644 .sampo/changesets/quiet-mcp-identify.md diff --git a/.sampo/changesets/quiet-mcp-identify.md b/.sampo/changesets/quiet-mcp-identify.md new file mode 100644 index 000000000..8a8fd3b16 --- /dev/null +++ b/.sampo/changesets/quiet-mcp-identify.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +MCP analytics no longer sends standalone `$identify` events, so insights, funnels, or cohorts built on MCP `$identify` stop receiving new data. The `identify` callback still sets `distinct_id`, `$set` and `$groups` on every event. diff --git a/examples/mcp_analytics_demo.py b/examples/mcp_analytics_demo.py index 23f30b6cc..e2d274608 100644 --- a/examples/mcp_analytics_demo.py +++ b/examples/mcp_analytics_demo.py @@ -72,7 +72,7 @@ async def main() -> None: list_handler = server._mcp_server.request_handlers[mcp_types.ListToolsRequest] await list_handler(mcp_types.ListToolsRequest(method="tools/list")) - # tool calls -> $mcp_initialize (lazy, once), $identify, $mcp_tool_call x3, $exception + # tool calls -> $mcp_initialize (lazy, once), $mcp_tool_call x3, $exception await server._tool_manager.call_tool( "add", {"a": 2, "b": 3, "context": "adding two numbers to demo the python mcp sdk"}, diff --git a/posthog/mcp/_event_types.py b/posthog/mcp/_event_types.py index 75778dcd8..7392f90a9 100644 --- a/posthog/mcp/_event_types.py +++ b/posthog/mcp/_event_types.py @@ -13,7 +13,6 @@ class MCPAnalyticsEventType: """Protocol-shaped event types observed by the SDK (internal dispatch keys).""" - IDENTIFY = "posthog:identify" CUSTOM = "posthog:custom" MCP_FEEDBACK = "mcp:feedback" MCP_MISSING_CAPABILITY = "mcp:missing_capability" diff --git a/posthog/mcp/_instrumentation.py b/posthog/mcp/_instrumentation.py index 167969069..03b66392c 100644 --- a/posthog/mcp/_instrumentation.py +++ b/posthog/mcp/_instrumentation.py @@ -377,9 +377,9 @@ async def prepare_request( the session id to stamp on the event for this request. ``conversation_id`` is the agent's handle for this request, and when present - it anchors the session (ADR-0004) so every event of the request — identify, - initialize, and the call itself — lands in the conversation's session rather - than this instance's. + it anchors the session (ADR-0004) so every event of the request — initialize + and the call itself — lands in the conversation's session rather than this + instance's. Callers pass it only for a handle the agent **echoed**. A freshly minted one is unproven: this runs before the call, so delivery cannot be known yet, and @@ -412,9 +412,7 @@ async def prepare_request( and not _is_sse_request(extra) ): _warn_stateless_session_not_wired(data) - identify_event = await handle_identify(data, session_id, request, extra) - if identify_event: - fire_and_forget(capture_event(data, identify_event), data) + await handle_identify(data, session_id, request, extra) await _maybe_emit_initialize( data, session_id, client_name, client_version, extra, protocol_version ) diff --git a/posthog/mcp/_internal.py b/posthog/mcp/_internal.py index 12bc83d28..8da3cd8d0 100644 --- a/posthog/mcp/_internal.py +++ b/posthog/mcp/_internal.py @@ -12,7 +12,6 @@ from __future__ import annotations import asyncio -import json import weakref from collections import OrderedDict from dataclasses import dataclass, field @@ -139,25 +138,6 @@ def set_server_tracking_data(server: Any, data: MCPAnalyticsData) -> None: _server_tracking[server] = data -def are_identities_equal(a: UserIdentity, b: UserIdentity) -> bool: - if a.distinct_id != b.distinct_id: - return False - if json.dumps(a.groups or {}, sort_keys=True) != json.dumps( - b.groups or {}, sort_keys=True - ): - return False - a_props = a.properties or {} - b_props = b.properties or {} - if set(a_props.keys()) != set(b_props.keys()): - return False - for key in a_props: - if json.dumps(a_props[key], sort_keys=True, default=str) != json.dumps( - b_props[key], sort_keys=True, default=str - ): - return False - return True - - def merge_identities( previous: Optional[UserIdentity], nxt: UserIdentity ) -> UserIdentity: @@ -176,35 +156,18 @@ async def _maybe_await(value: Any) -> Any: return value -def _captured_extra(extra: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]: - """Project ``extra`` down to JSON-safe scalars before it is captured. - - Callbacks (``identify``, ``event_properties``, ``intent_fallback``) receive - the full dict — on MCP SDK v2 that includes the raw request ``ctx`` so hosts - can read headers. Captured event parameters must not: the sanitizer leaves - opaque objects untouched and truncation stringifies them, which would ship - whatever the object's repr carries (headers, auth material, transport state) - to PostHog without key-based redaction.""" - if extra is None: - return None - return { - key: value - for key, value in extra.items() - if value is None or isinstance(value, (str, int, float, bool)) - } - - async def handle_identify( data: MCPAnalyticsData, session_id: str, request: Dict[str, Any], extra: Optional[Dict[str, Any]] = None, -) -> Optional[Dict[str, Any]]: - """Resolve the optional ``identify`` callback, dedupe against the identity - cache, and return an ``$identify`` event to emit only when the identity has - materially changed (otherwise ``None``).""" +) -> None: + """Resolve the optional ``identify`` callback and merge the result into the + session's cached identity. Every event of the session then carries it as + ``distinct_id``/``$set``, so no standalone ``$identify`` is sent: without an + ``$anon_distinct_id`` it would merge no person in ingestion.""" if not data.options.identify: - return None + return try: identify = data.options.identify @@ -217,29 +180,16 @@ async def handle_identify( log( f"Warning: Supplied identify function returned null for session {session_id}" ) - return None + return previous = data.identified_sessions.get(session_id) - merged = merge_identities(previous, identity_result) - has_changed = not (previous and are_identities_equal(previous, merged)) - data.identified_sessions.set(session_id, merged) - - if has_changed: - from ._event_types import MCPAnalyticsEventType - - log(f"Identified session {session_id}") - return { - "session_id": session_id, - "resource_name": _get_request_resource_name(request), - "event_type": MCPAnalyticsEventType.IDENTIFY, - "parameters": {"request": request, "extra": _captured_extra(extra)}, - "timestamp": datetime.now(timezone.utc), - } + data.identified_sessions.set( + session_id, merge_identities(previous, identity_result) + ) except Exception as error: # noqa: BLE001 log( f"Error: identify function threw while identifying session {session_id} - {error}" ) - return None async def resolve_event_properties( @@ -254,18 +204,3 @@ async def resolve_event_properties( except Exception as e: # noqa: BLE001 log(f"event_properties callback error: {e}") return None - - -def _get_request_resource_name(request: Any) -> str: - """The thing the request acts on: a tool/prompt ``name``, or the ``uri`` of a - resource read — which is the only name a ``resources/read`` request carries.""" - if not isinstance(request, dict): - return "Unknown" - params = request.get("params") - if not isinstance(params, dict): - return "Unknown" - for key in ("name", "uri"): - value = params.get(key) - if isinstance(value, str): - return value - return "Unknown" diff --git a/posthog/mcp/_posthog_events.py b/posthog/mcp/_posthog_events.py index 15e80fa98..b5c3add23 100644 --- a/posthog/mcp/_posthog_events.py +++ b/posthog/mcp/_posthog_events.py @@ -22,7 +22,6 @@ _BUILT_IN_EVENT_NAME_BY_TYPE = { MCPAnalyticsEventType.CUSTOM: PostHogMCPAnalyticsEvent.CUSTOM, - MCPAnalyticsEventType.IDENTIFY: PostHogMCPAnalyticsEvent.IDENTIFY, MCPAnalyticsEventType.MCP_FEEDBACK: PostHogMCPAnalyticsEvent.FEEDBACK, MCPAnalyticsEventType.MCP_MISSING_CAPABILITY: PostHogMCPAnalyticsEvent.MISSING_CAPABILITY, MCPAnalyticsEventType.MCP_INITIALIZE: PostHogMCPAnalyticsEvent.INITIALIZE, diff --git a/posthog/mcp/constants.py b/posthog/mcp/constants.py index 525529403..2d26e1631 100644 --- a/posthog/mcp/constants.py +++ b/posthog/mcp/constants.py @@ -52,6 +52,7 @@ class PostHogMCPAnalyticsEvent: CUSTOM = "$mcp_custom" EXCEPTION = "$exception" FEEDBACK = "$mcp_feedback" + # Deprecated: the SDK no longer sends `$identify`. IDENTIFY = "$identify" INITIALIZE = "$mcp_initialize" MISSING_CAPABILITY = "$mcp_missing_capability" diff --git a/posthog/test/mcp/test_fastmcp.py b/posthog/test/mcp/test_fastmcp.py index f3e904982..0bcc88c1d 100644 --- a/posthog/test/mcp/test_fastmcp.py +++ b/posthog/test/mcp/test_fastmcp.py @@ -256,8 +256,7 @@ async def test_identify_sets_distinct_id_and_groups(): assert calls[0]["distinct_id"] == "user_42" assert calls[0]["properties"]["$groups"] == {"organization": "org_7"} assert calls[0]["options"] == {} - # an $identify event was emitted - assert _events(client, "$identify") + assert not _events(client, "$identify") async def test_instrument_is_idempotent(): diff --git a/posthog/test/mcp/test_lowlevel.py b/posthog/test/mcp/test_lowlevel.py index b51a5a10a..62dbd1ed0 100644 --- a/posthog/test/mcp/test_lowlevel.py +++ b/posthog/test/mcp/test_lowlevel.py @@ -291,7 +291,7 @@ async def test_failed_resource_listing_is_captured() -> None: assert "listing unavailable" in json.dumps(exceptions[0]["properties"]) -async def test_identify_on_a_resource_read_is_named_by_the_uri() -> None: +async def test_identify_attributes_a_resource_read_without_an_identify_event() -> None: server = make_server() client = FakeClient() instrument( @@ -304,21 +304,13 @@ async def test_identify_on_a_resource_read_is_named_by_the_uri() -> None: await server.request_handlers[mcp_types.ReadResourceRequest]( mcp_types.ReadResourceRequest( - params=mcp_types.ReadResourceRequestParams( - uri="https://fakeuser:fakepass@example.com/guide" - ) + params=mcp_types.ReadResourceRequestParams(uri="https://example.com/guide") ) ) await _flush() - identified = _events(client, "$identify") - assert len(identified) == 1 - # A resources/read request carries no `name`, so the uri is the only thing - # that can name it — sanitized like any other captured URL. - assert ( - identified[0]["properties"]["$mcp_resource_name"] - == "https://%5Bredacted%5D@example.com/guide" - ) + assert not _events(client, "$identify") + assert _events(client, "$mcp_resource_read")[0]["distinct_id"] == "user_42" async def test_tool_call_success_captures_intent(): diff --git a/posthog/test/mcp/test_pipeline.py b/posthog/test/mcp/test_pipeline.py index 7ec183ef9..9a6cb6c69 100644 --- a/posthog/test/mcp/test_pipeline.py +++ b/posthog/test/mcp/test_pipeline.py @@ -706,11 +706,6 @@ def test_redact_pii_is_not_quadratic_on_pathological_input(): "Get_Organization_Memberships", "Get_Organization_Memberships", ), - ( - MCPAnalyticsEventType.IDENTIFY, - "https://fakeuser:fakepass@example.com/doc", - "https://%5Bredacted%5D@example.com/doc", - ), ( MCPAnalyticsEventType.MCP_RESOURCES_READ, "https://example.com/guide?token=fakesecret", diff --git a/posthog/test/mcp/test_units.py b/posthog/test/mcp/test_units.py index c07c85ab6..49316a1fb 100644 --- a/posthog/test/mcp/test_units.py +++ b/posthog/test/mcp/test_units.py @@ -28,7 +28,6 @@ from posthog.mcp._internal import ( IdentityCache, MCPAnalyticsData, - are_identities_equal, merge_identities, ) from posthog.mcp.session import ( @@ -385,13 +384,6 @@ async def test_resolve_session_id_rolls_over_after_inactivity(): # --- identity cache / merge -------------------------------------------------- -def test_are_identities_equal(): - a = UserIdentity(distinct_id="u1", properties={"plan": "pro"}, groups={"org": "o1"}) - b = UserIdentity(distinct_id="u1", properties={"plan": "pro"}, groups={"org": "o1"}) - assert are_identities_equal(a, b) - assert not are_identities_equal(a, UserIdentity(distinct_id="u2")) - - def test_merge_identities_merges_properties_and_keeps_distinct_id(): merged = merge_identities( UserIdentity(distinct_id="u1", properties={"a": 1}), diff --git a/posthog/test/mcp/test_v2_mcpserver.py b/posthog/test/mcp/test_v2_mcpserver.py index 7fbf0919d..0525da3e0 100644 --- a/posthog/test/mcp/test_v2_mcpserver.py +++ b/posthog/test/mcp/test_v2_mcpserver.py @@ -235,14 +235,12 @@ async def test_identify_sets_distinct_id_and_groups(): calls = _events(client, "$mcp_tool_call") assert calls[0]["distinct_id"] == "user_42" assert calls[0]["properties"]["$groups"] == {"organization": "org_7"} - assert _events(client, "$identify") + assert not _events(client, "$identify") -async def test_identify_callback_sees_ctx_but_capture_does_not(): +async def test_identify_callback_sees_ctx(): """The v2 adapters hand the raw request ``ctx`` to callbacks via ``extra`` so - hosts can read headers — but the captured $identify parameters must carry - only a scalar projection, or the stringified context (headers, transport - state) would ship to PostHog without key-based redaction.""" + hosts can read headers.""" server = make_server() client = FakeClient() seen = {} @@ -258,16 +256,8 @@ def identify(request, extra): ) await _flush() - # the callback got the live context object... assert seen["extra"]["ctx"] is not None - # ...but the captured event only carries JSON-safe scalars - identify_events = _events(client, "$identify") - assert identify_events - captured_extra = identify_events[0]["properties"]["$mcp_parameters"]["extra"] - assert "ctx" not in captured_extra - assert set(captured_extra) <= {"session_id"} - async def test_structured_output_tool_gets_the_conversation_handle(): """A tool that declares an output schema is served to clients that read diff --git a/posthog/test/mcp/test_v2_wire_dual_era.py b/posthog/test/mcp/test_v2_wire_dual_era.py index 0e89b69b1..58fbf4e9a 100644 --- a/posthog/test/mcp/test_v2_wire_dual_era.py +++ b/posthog/test/mcp/test_v2_wire_dual_era.py @@ -19,6 +19,7 @@ from contextlib import asynccontextmanager import httpx +import pytest from mcp.server.mcpserver import MCPServer from posthog.mcp import ( @@ -26,7 +27,7 @@ derive_session_id_from_conversation, instrument, ) -from posthog.mcp.types import MCPAnalyticsOptions +from posthog.mcp.types import MCPAnalyticsOptions, UserIdentity from posthog.test.mcp._helpers import ( FakeClient, events_named as _events, @@ -241,6 +242,48 @@ async def test_modern_result_shape_survives_instrumentation(): assert result.get("structuredContent") == bare_result.get("structuredContent") +@pytest.mark.parametrize("era", ["legacy", "modern"]) +async def test_identify_sends_no_identify_event_across_instances(era): + """Each call lands on a fresh instance with no session token, so every + identity is first-seen. Attribution must still come from the callback.""" + client = FakeClient() + options = MCPAnalyticsOptions( + enable_conversation_id=False, + identify=lambda request, extra: UserIdentity( + distinct_id="user_42", properties={"plan": "paid"} + ), + ) + + for request_id in (1, 2): + server = make_server() + instrument(server, client, options) + async with wire(server) as http: + if era == "modern": + response = await modern_call( + http, "add", {"a": 1, "b": 2, "context": "pod"}, request_id + ) + else: + call = rpc( + "tools/call", + {"name": "add", "arguments": {"a": 1, "b": 2, "context": "pod"}}, + request_id, + ) + headers = { + **legacy_headers(), + "mcp-protocol-version": LEGACY_PROTOCOL_VERSION, + } + response = await http.post("/mcp", json=call, headers=headers) + assert response.status_code == 200 + await _flush() + + assert not _events(client, "$identify") + calls = _events(client, "$mcp_tool_call") + assert len(calls) == 2 + for call in calls: + assert call["distinct_id"] == "user_42" + assert call["properties"]["$set"] == {"plan": "paid"} + + # --- legacy era (2025-11-25) on the v2 SDK ------------------------------------- From da642879fb288f39d1b9aa85e6a8ceacb48ac7a8 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:36:26 +0000 Subject: [PATCH 22/70] chore: Release v7.72.0 [skip ci] (cherry picked from commit 876b955942cf86579dfda7032ec03a42de06769f) --- .sampo/changesets/quiet-mcp-identify.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/quiet-mcp-identify.md diff --git a/.sampo/changesets/quiet-mcp-identify.md b/.sampo/changesets/quiet-mcp-identify.md deleted file mode 100644 index 8a8fd3b16..000000000 --- a/.sampo/changesets/quiet-mcp-identify.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -MCP analytics no longer sends standalone `$identify` events, so insights, funnels, or cohorts built on MCP `$identify` stop receiving new data. The `identify` callback still sets `distinct_id`, `$set` and `$groups` on every event. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 0a671dafb..bc04fd642 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.108 — 2026-10-19 + +### Patch changes + +- Updated dependencies: posthog@7.72.0 + ## 0.1.107 — 2026-10-16 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 36dfc3477..f4f2bf83b 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.107" +version = "0.1.108" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 1baddc69b..d86fb82b4 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.72.0 — 2026-10-19 + +### Minor changes + +- [facd617](https://github.com/posthog/posthog-python/commit/facd617491a74d8c3c751f0a628661b3817b250d) MCP analytics no longer sends standalone `$identify` events, so insights, funnels, or cohorts built on MCP `$identify` stop receiving new data. The `identify` callback still sets `distinct_id`, `$set` and `$groups` on every event. — Thanks @gesh! + ## 7.71.0 — 2026-10-16 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index 08106028b..36a0dbd29 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.71.0" +VERSION = "7.72.0" diff --git a/pyproject.toml b/pyproject.toml index 471f5d548..0de5632eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.71.0" +version = "7.72.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index e7fbd5d88..966538652 100644 --- a/uv.lock +++ b/uv.lock @@ -2491,7 +2491,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.107" +version = "0.1.108" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2821,7 +2821,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.71.0" +version = "7.72.0" source = { editable = "." } dependencies = [ { name = "distro" }, From 2eaa16c3d0bacbd59066425659166b53e1156b48 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 14:36:31 +0000 Subject: [PATCH 23/70] Update generated references (cherry picked from commit b8327de20f3ed1ba59863c1cbb7e086655cdce12) --- .../posthog-python-references-7.72.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.72.0.json diff --git a/references/posthog-python-references-7.72.0.json b/references/posthog-python-references-7.72.0.json new file mode 100644 index 000000000..05421adfc --- /dev/null +++ b/references/posthog-python-references-7.72.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.72.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 342930ffc..05421adfc 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.71.0", + "version": "7.72.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 11d4ad33ecc139bfb3767a41cfc5c7abaca175b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 13:13:16 -0400 Subject: [PATCH 24/70] chore(deps): bump the github-actions group with 6 updates (#1083) Bumps the github-actions group with 6 updates: | Package | From | To | | --- | --- | --- | | [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `10.2.0` | `10.3.0` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.38.2` | `4.38.3` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.38.2` | `4.38.3` | | [actions/create-github-app-token](https://github.com/actions/create-github-app-token) | `3.2.0` | `3.3.0` | | [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) | `e2a55d2ffb04f378e9626c28d38b36d230d1e12f` | `683b588c487a69d01f6c6ddf40f036ff682cc2c8` | | [PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml](https://github.com/posthog/posthog-sdk-test-harness) | `1.13.1` | `1.15.0` | Updates `astral-sh/setup-uv` from 10.2.0 to 10.3.0 - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/c18668ad3cf93ea998bef934396af7bb5c839dc7...1c37ad07a6a961277cf70c0d37d6f313000f5884) Updates `github/codeql-action/init` from 4.38.2 to 4.38.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d) Updates `github/codeql-action/analyze` from 4.38.2 to 4.38.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d) Updates `actions/create-github-app-token` from 3.2.0 to 3.3.0 - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Changelog](https://github.com/actions/create-github-app-token/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/create-github-app-token/compare/bcd2ba49218906704ab6c1aa796996da409d3eb1...64ab729a6294000f5aa4a4bc0b73d1f32bc45510) Updates `dtolnay/rust-toolchain` from e2a55d2ffb04f378e9626c28d38b36d230d1e12f to 683b588c487a69d01f6c6ddf40f036ff682cc2c8 - [Release notes](https://github.com/dtolnay/rust-toolchain/releases) - [Commits](https://github.com/dtolnay/rust-toolchain/compare/e2a55d2ffb04f378e9626c28d38b36d230d1e12f...683b588c487a69d01f6c6ddf40f036ff682cc2c8) Updates `PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml` from 1.13.1 to 1.15.0 - [Release notes](https://github.com/posthog/posthog-sdk-test-harness/releases) - [Changelog](https://github.com/PostHog/posthog-sdk-test-harness/blob/main/CHANGELOG.md) - [Commits](https://github.com/posthog/posthog-sdk-test-harness/compare/e32f08bd30fab57ce543da5808a668d0fda697b0...64ffa6ab19166541880c077d349abe18a7e42395) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 10.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: github/codeql-action/init dependency-version: 4.38.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: github/codeql-action/analyze dependency-version: 4.38.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions - dependency-name: actions/create-github-app-token dependency-version: 3.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions - dependency-name: dtolnay/rust-toolchain dependency-version: 683b588c487a69d01f6c6ddf40f036ff682cc2c8 dependency-type: direct:production dependency-group: github-actions - dependency-name: PostHog/posthog-sdk-test-harness/.github/workflows/test-sdk-action.yml dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 3822271b1f45d31e24e717b61ad5c2db1224503d) --- .github/workflows/ci.yml | 12 ++++++------ .github/workflows/codeql.yml | 4 ++-- .github/workflows/posthog-upgrade.yml | 2 +- .github/workflows/release.yml | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41336cc71..f92d5194d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,7 +109,7 @@ jobs: python-version: 3.11.11 - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -137,7 +137,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -176,7 +176,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -242,7 +242,7 @@ jobs: - name: Install uv if: steps.changes.outputs.changed == 'true' - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -323,7 +323,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -378,7 +378,7 @@ jobs: python-version: 3.12 - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 262d83807..fcaca264b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Initialize CodeQL - uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 + uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -40,6 +40,6 @@ jobs: trap-caching: false - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 + uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/posthog-upgrade.yml b/.github/workflows/posthog-upgrade.yml index 19a04aa24..585f2958b 100644 --- a/.github/workflows/posthog-upgrade.yml +++ b/.github/workflows/posthog-upgrade.yml @@ -42,7 +42,7 @@ jobs: token: ${{ steps.upgrader.outputs.token }} - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.12.21" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6987f2f53..2de109583 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,7 +83,7 @@ jobs: - name: Get GitHub App token id: releaser - uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: client-id: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_APP_ID }} private-key: ${{ secrets.GH_APP_POSTHOG_PYTHON_RELEASER_PRIVATE_KEY }} @@ -101,13 +101,13 @@ jobs: python-version: 3.11.11 - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true - name: Install Rust - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 with: toolchain: 1.91.1 components: cargo @@ -306,7 +306,7 @@ jobs: python-version: 3.11.11 - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true @@ -473,13 +473,13 @@ jobs: python-version: 3.11.11 - name: Install uv - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 + uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: version: "0.11.32" enable-cache: true - name: Install Rust - uses: dtolnay/rust-toolchain@e2a55d2ffb04f378e9626c28d38b36d230d1e12f + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 with: toolchain: 1.91.1 components: cargo From 810c6e31f408985c6cae5688a40732d33d345e8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 13:13:22 -0400 Subject: [PATCH 25/70] chore(deps): bump the ai-providers group with 6 updates (#1082) Bumps the ai-providers group with 6 updates: | Package | From | To | | --- | --- | --- | | [langchain](https://github.com/langchain-ai/langchain) | `1.4.3` | `1.4.4` | | [anthropic](https://github.com/anthropics/anthropic-sdk-python) | `1.11.0` | `1.13.0` | | [langgraph](https://github.com/langchain-ai/langgraph) | `1.2.13` | `1.2.14` | | [langchain-core](https://github.com/langchain-ai/langchain) | `1.6.6` | `1.6.9` | | [langchain-openai](https://github.com/langchain-ai/langchain) | `1.6.7` | `1.7.0` | | [google-genai](https://github.com/googleapis/python-genai) | `2.28.0` | `2.29.0` | Updates `langchain` from 1.4.3 to 1.4.4 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain==1.4.3...langchain==1.4.4) Updates `anthropic` from 1.11.0 to 1.13.0 - [Release notes](https://github.com/anthropics/anthropic-sdk-python/releases) - [Changelog](https://github.com/anthropics/anthropic-sdk-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/anthropics/anthropic-sdk-python/compare/v1.11.0...v1.13.0) Updates `langgraph` from 1.2.13 to 1.2.14 - [Release notes](https://github.com/langchain-ai/langgraph/releases) - [Commits](https://github.com/langchain-ai/langgraph/compare/1.2.13...1.2.14) Updates `langchain-core` from 1.6.6 to 1.6.9 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-core==1.6.6...langchain-core==1.6.9) Updates `langchain-openai` from 1.6.7 to 1.7.0 - [Release notes](https://github.com/langchain-ai/langchain/releases) - [Commits](https://github.com/langchain-ai/langchain/compare/langchain-openai==1.6.7...langchain-openai==1.7.0) Updates `google-genai` from 2.28.0 to 2.29.0 - [Release notes](https://github.com/googleapis/python-genai/releases) - [Changelog](https://github.com/googleapis/python-genai/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/python-genai/compare/v2.28.0...v2.29.0) --- updated-dependencies: - dependency-name: langchain dependency-version: 1.4.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: anthropic dependency-version: 1.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ai-providers - dependency-name: langgraph dependency-version: 1.2.14 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: langchain-core dependency-version: 1.6.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ai-providers - dependency-name: langchain-openai dependency-version: 1.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ai-providers - dependency-name: google-genai dependency-version: 2.29.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: ai-providers ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 9b70476eeeea0f653212bf3f7fe7abba8508b329) --- uv.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/uv.lock b/uv.lock index 966538652..bd292e4f2 100644 --- a/uv.lock +++ b/uv.lock @@ -226,7 +226,7 @@ wheels = [ [[package]] name = "anthropic" -version = "1.11.0" +version = "1.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -237,9 +237,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ad/12/9a6ffa397b172adb040008d934a1dfd85d0e4cefc77489416db294ffc880/anthropic-1.11.0.tar.gz", hash = "sha256:3906fabac7ad7b5b46c6186040398fc7826885c77ce34e4dd7849de16fc8d0f8", size = 1390390, upload-time = "2026-09-30T22:58:21.098Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/ed/e76e50601b7c476bcb9a2a7a4c4dab6f1a9b2c03e3922de8b3ec599ccbc5/anthropic-1.13.0.tar.gz", hash = "sha256:ad11d9bb9adafdfea26113943bcde9973e2a439ebeeda6c89ff3e3d85bb2f5c1", size = 1567362, upload-time = "2026-10-09T15:29:08.803Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/6f/20edcd2956cac68042b1bcdd13ab3311447519f86b26929ff268dc74c650/anthropic-1.11.0-py3-none-any.whl", hash = "sha256:52f97b2c485cca7ac66058374f5073a3febb7e6849b16989c145d602a3efee21", size = 1681654, upload-time = "2026-09-30T22:58:22.925Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9a/a835340c91bc9a233bd54c05fc438fe07cbef71ca667f24f3892a268ae20/anthropic-1.13.0-py3-none-any.whl", hash = "sha256:157bd74dbf6a595cf9e5fcac557c791fd297924dc48261f57470c2ed6f4e6671", size = 1958595, upload-time = "2026-10-09T15:29:10.689Z" }, ] [[package]] @@ -1138,7 +1138,7 @@ requests = [ [[package]] name = "google-genai" -version = "2.28.0" +version = "2.29.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1152,9 +1152,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/59/16/4af15d65cb72ebc21a99c5e64f09072e97334c05a48d4cede19c347e6ad2/google_genai-2.28.0.tar.gz", hash = "sha256:970cb2eaf1951949851c3e0a5b70265cfea8a408fb7361c7c980a84d90672bf2", size = 707359, upload-time = "2026-10-02T17:58:14.454Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/2b/977616ef350e51d3d263eb43be23a91be793544cd937b51c0fac313be233/google_genai-2.29.0.tar.gz", hash = "sha256:124d3eef9ff6b9e4ea548f95ff5b7721683e7990c0a936b006d9e2ab61ea897d", size = 706902, upload-time = "2026-10-07T22:22:57.153Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/4b/47278c34757293ba8d9156090d38e1c45fac9a47c50176acff7f77ae9a66/google_genai-2.28.0-py3-none-any.whl", hash = "sha256:cdee15e2fbfea08ea61bce6e5bfbb3301db4bd13a52dccfa8c8d1167e37ca1cc", size = 1168554, upload-time = "2026-10-02T17:58:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/b8/27/a3dede4a1deb21f7fde6a171daa039bf0ea149a5e7826a785e8f109a6e13/google_genai-2.29.0-py3-none-any.whl", hash = "sha256:7adda55cb6746fb46d38ad3202c3372840b96eede964b5fb3df1469cd4998570", size = 1167603, upload-time = "2026-10-07T22:22:55.215Z" }, ] [[package]] @@ -1632,16 +1632,16 @@ wheels = [ [[package]] name = "langchain" -version = "1.4.3" +version = "1.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, { name = "langgraph" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a2/aa/0fcaf5d7dbebcf7d0eb74293dca5aee6f0558242731f4dee4a800cc2431d/langchain-1.4.3.tar.gz", hash = "sha256:aed5c1a7cd581f70ddc076b75fdbcbae8031b8373983f86efd287aa70798abc2", size = 738607, upload-time = "2026-09-28T20:17:24.38Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/a4/a3ceefc3ec734912ca3a21dd79a5e4a98af73015a87e64d284a92cd5572c/langchain-1.4.4.tar.gz", hash = "sha256:baac6e13c08460e1decd0e60061b9a87c07135f1c977424040b0b57ff7bc7887", size = 742902, upload-time = "2026-10-08T22:14:10.86Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/03/8cc027f9d297473de94f134546dae2bfca255161ebbda988522fc509e1d5/langchain-1.4.3-py3-none-any.whl", hash = "sha256:0334066939dd1c7551889727ed2d09a72dea7a6aed2193ffb61817fb658d8921", size = 164708, upload-time = "2026-09-28T20:17:22.978Z" }, + { url = "https://files.pythonhosted.org/packages/02/36/c348f812eb37a137de2c80140ed1324ab11b75fa5a845e3f1035bacaac4a/langchain-1.4.4-py3-none-any.whl", hash = "sha256:2fd27e9a2d54ebcd915ac5ea51d79c772e020567ef6c6a76678182055489b804", size = 165363, upload-time = "2026-10-08T22:14:09.321Z" }, ] [[package]] @@ -1702,7 +1702,7 @@ wheels = [ [[package]] name = "langchain-core" -version = "1.6.6" +version = "1.6.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -1716,14 +1716,14 @@ dependencies = [ { name = "typing-extensions" }, { name = "uuid-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/87/9e5d393bbcec068c51becc255a15aacfd8a14ac5826179751c1c320e5258/langchain_core-1.6.6.tar.gz", hash = "sha256:67616d984c085009be2c381c2efd330d32429a58aebab295b4f51b6573964511", size = 1007227, upload-time = "2026-09-29T14:52:54.598Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/d3/e9611e44e62ab8175127e137587c62dc2ed00e2615aebd89dfdb77f5fba0/langchain_core-1.6.9.tar.gz", hash = "sha256:34394228603e6f0bd24ce4e773b58b7d160e1b8cf489ecb350cf41f5366f5e92", size = 1010051, upload-time = "2026-10-08T20:11:19.881Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/10/8c00b4dc094886314c907ec7ead258dfee28948cf44175976cc4fba9aba8/langchain_core-1.6.6-py3-none-any.whl", hash = "sha256:d9a71e312ab7443701238750e04a57aefc037c4f1ec82837c8a1609d9a14a9b1", size = 572080, upload-time = "2026-09-29T14:52:53.213Z" }, + { url = "https://files.pythonhosted.org/packages/49/41/fdcdd869c052874b17e2325c986cf8c2fc6bbefa3b9d5404dd64dfffb12a/langchain_core-1.6.9-py3-none-any.whl", hash = "sha256:2bacea12270fd4cfdeeefdc5977e7e8b3c30814c509534d1ef43f4e5b7d3f657", size = 572951, upload-time = "2026-10-08T20:11:18.189Z" }, ] [[package]] name = "langchain-openai" -version = "1.6.7" +version = "1.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1731,9 +1731,9 @@ dependencies = [ { name = "openai" }, { name = "tiktoken" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/2f/367068190b5a7d181996ad7899052394f0276468c92be48e0b7dab63716a/langchain_openai-1.6.7.tar.gz", hash = "sha256:b276a01b43c5287382f62070a4e1ca5bad5581fadab8c086e46b79daa4bf975d", size = 3380633, upload-time = "2026-09-30T15:12:03.1Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/68/dd7f7ef76efe58222d37f1b1a5595b1bb368fc9165f71526db26e4c5759e/langchain_openai-1.7.0.tar.gz", hash = "sha256:7df2db16d32320ba563b7e4291a71ec6bf7b0ea8a5369ed2a0501d74928ea6d0", size = 3404806, upload-time = "2026-10-08T16:07:35.135Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/d9/b3db61c6c15766c999194a9cba0b9c5035567b7e0dd1c1a94a6d76448cd6/langchain_openai-1.6.7-py3-none-any.whl", hash = "sha256:e1b9b318fafc47b2dbc3485778aa23f809195065ee313611c188af29744b8e8e", size = 127883, upload-time = "2026-09-30T15:12:01.876Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ef/3f40387231281eaefb0bec31bfa86a7d533de9d90b46802c3e24d436a163/langchain_openai-1.7.0-py3-none-any.whl", hash = "sha256:a4d319385019c010c579b39e8951e4d5ededeacf94cd9c79162f4cb7ecba50fb", size = 145622, upload-time = "2026-10-08T16:07:33.119Z" }, ] [[package]] @@ -1762,7 +1762,7 @@ wheels = [ [[package]] name = "langgraph" -version = "1.2.13" +version = "1.2.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "langchain-core" }, @@ -1772,9 +1772,9 @@ dependencies = [ { name = "pydantic" }, { name = "xxhash" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c3/22/75ab5e7d13c842d8dc68f115cf6cc5a651a8d5a993e72a621c98bfb2b1cd/langgraph-1.2.13.tar.gz", hash = "sha256:a3cae71d4cb88455d7a8887109665525aefe4ab13fe941d653cd4b6de2af45c6", size = 752793, upload-time = "2026-10-05T17:51:21.566Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/3f/6e60789eab2c5ceaf34ba2c626ac345df93b026bbe7385018aa4b9c30397/langgraph-1.2.14.tar.gz", hash = "sha256:5b1a72b7a7f994ac6947b7751fbbe00e949f8bb44d9ab78881604b703247ae55", size = 752793, upload-time = "2026-10-06T14:41:19.789Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/8e/b7471af7fc72c218e545c74454c386a4b0867a8a15c9893db1d28464f492/langgraph-1.2.13-py3-none-any.whl", hash = "sha256:5d45a021e043aaf39f32122e620eacfd1245aa84dfaa84b0814cef0f4ac78eb4", size = 255979, upload-time = "2026-10-05T17:51:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/ec/4a/f976df0d3cf7fb7986dc39f656c6b7b5655834430e9bdfaef1e1e4fffaba/langgraph-1.2.14-py3-none-any.whl", hash = "sha256:e3f5f8ff4259f9281b73ff50fc9ef5cc3b025b8936b8283ecdca7cc0c4128690", size = 255980, upload-time = "2026-10-06T14:41:18.129Z" }, ] [[package]] @@ -1805,7 +1805,7 @@ wheels = [ [[package]] name = "langgraph-sdk" -version = "0.4.4" +version = "0.4.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, @@ -1814,9 +1814,9 @@ dependencies = [ { name = "orjson" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3f/ae/91446c1fffa04a2dc1f81afbfb5bfff3590452891a72bd9098a656ab2657/langgraph_sdk-0.4.4.tar.gz", hash = "sha256:4e651ffa09de695681579396375377bdde23bedbc8e35b070e615cbd5af7da8b", size = 345789, upload-time = "2026-08-27T21:25:22.593Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/85/54edf4902c0378510f09a009f64e3d3f5644aeeb51d13cf67ec380a5245b/langgraph_sdk-0.4.6.tar.gz", hash = "sha256:ea5b1749d70987d741c9b9fe2b7e1c5f7da7e4d102f64e390333c1890c9bbd5b", size = 350632, upload-time = "2026-10-06T14:17:53.641Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/d5/2ad7f3a835c6fcebf58b6669552536ecd52d2dfe4cf49c6c36648fd83572/langgraph_sdk-0.4.4-py3-none-any.whl", hash = "sha256:39afe416c91742925e6f8a93715f566d499b36e1b636b804a4ffe3190e4f4e64", size = 162270, upload-time = "2026-08-27T21:25:21.072Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c7/69d13026db3577c157877dea47a9dc5fffd3dcde2d1ab8009fa8f7e5f6a6/langgraph_sdk-0.4.6-py3-none-any.whl", hash = "sha256:57122b02bda41d37a97a5e09eb018aa8c9b3dc85c433880073779bd9324b7eea", size = 162390, upload-time = "2026-10-06T14:17:52.134Z" }, ] [[package]] From c878a8176549aa36e822ca2a498d8d64a5c3d02a Mon Sep 17 00:00:00 2001 From: Radu Raicea Date: Mon, 19 Oct 2026 15:18:22 -0400 Subject: [PATCH 26/70] feat(llma): support scorer and experiment tags (#1085) (cherry picked from commit b086f65437c4904310279646da76321a80294056) --- .sampo/changesets/evaluation-tags.md | 5 + .../example-offline-evaluations/README.md | 37 ++++++++ posthog/ai/evaluations/_client.py | 50 ++++++++++ posthog/ai/evaluations/_scorer_types.py | 2 + posthog/ai/evaluations/_scorers.py | 67 ++++++++++--- posthog/ai/evaluations/_tags.py | 28 ++++++ posthog/test/ai/test_evaluations.py | 95 +++++++++++++++++++ posthog/test/ai/test_evaluations_scorers.py | 92 ++++++++++++++++++ references/public_api_snapshot.txt | 19 ++-- 9 files changed, 376 insertions(+), 19 deletions(-) create mode 100644 .sampo/changesets/evaluation-tags.md create mode 100644 posthog/ai/evaluations/_tags.py diff --git a/.sampo/changesets/evaluation-tags.md b/.sampo/changesets/evaluation-tags.md new file mode 100644 index 000000000..ea734ed30 --- /dev/null +++ b/.sampo/changesets/evaluation-tags.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +Support tags in synchronous and asynchronous AI observability scorer creation, metadata updates, responses, and list filters. Add `get_tags()` and `set_tags()` to offline experiment handles for reading, replacing, and clearing experiment tags independently of uploads and completion. diff --git a/examples/example-offline-evaluations/README.md b/examples/example-offline-evaluations/README.md index c1ec2207f..279fe4e70 100644 --- a/examples/example-offline-evaluations/README.md +++ b/examples/example-offline-evaluations/README.md @@ -11,6 +11,8 @@ Offline evaluations must be enabled for your PostHog project. Use the project's | Create experiments, upload results, complete/fail | Personal API key or project secret key with `offline_evaluation_ingestion:write` | | Fetch scorers and versions | Personal API key with `llm_analytics:read` | | Create/update scorers and create versions | Personal API key with `llm_analytics:write` | +| Read experiment tags | Personal API key with `evaluation:read` | +| Replace experiment tags | Personal API key with `evaluation:write` | A personal key can cover both scorer management and uploads. Project secret keys can upload using a known scorer-version UUID without scorer read access. All operations use the explicit project/environment; scorer names are not unique. @@ -147,6 +149,41 @@ version = evaluations.scorers.get_version(scorer.id, updated.current_version_id) Scorer creation, version creation, and metadata updates are never automatically retried. If a response is lost, inspect server state before repeating a mutation. Version creation is not made idempotent by `base_version`. +## Tags + +Assign tags when creating a scorer, or replace them with a metadata update: + +```python +scorer = evaluations.scorers.create( + name="Answer relevance", + kind="numeric", + config=NumericScorerConfig(min=0, max=1), + tags=["quality", "production"], +) +print(scorer.tags) # ("production", "quality") +scorer = evaluations.scorers.update(scorer.id, tags=["quality"]) +page = evaluations.scorers.list(tags=["quality", "production"], tag_match="all") +evaluations.scorers.update(scorer.id, tags=[]) # Remove all tags. +``` + +Omitting `tags` preserves existing tags on updates. `tags=[]` clears them; `None` is not a valid replacement. Lists and tuples are accepted. The server trims and lowercases names, removes duplicates, and sorts them. Returned tags are immutable tuples. Writes accept up to 100 names, each nonblank and at most 255 characters after trimming. + +List filters accept up to 20 tags. `tag_match="any"` (the default) matches at least one selected tag; `"all"` requires every selected tag. An empty filter disables tag filtering. Preserve these filters when requesting subsequent pages. + +Experiment tags are separate from the creation/upload declaration. Set them on a newly created or resumed handle, including after completion: + +```python +experiment = evaluations.resume_experiment(experiment_id) +tags = experiment.set_tags(["quality", "baseline"]) +print(tags) # ("baseline", "quality") +print(experiment.get_tags()) +experiment.set_tags([]) # Remove all tags. +``` + +Reading and writing experiment tags require the personal-key scopes listed above; an upload-only project secret key cannot manage tags. Tag updates do not change the saved `submission`, lifecycle `receipt`, or scorer versions. They are not retried automatically: after a lost acknowledgment, read the current tags before deciding whether to repeat the replacement, since another caller may have edited them. + +The async client exposes the same API: await scorer methods and `experiment.get_tags()` / `experiment.set_tags(...)`. + ## Receipts, errors, and recovery Upload receipts contain persisted item/result UUIDs, original acceptance times, and `created` flags. `created=False` acknowledges an exact duplicate. A bulk upload returns `chunks`; each chunk commits independently. A malformed or incomplete acknowledgment raises rather than reporting success. diff --git a/posthog/ai/evaluations/_client.py b/posthog/ai/evaluations/_client.py index 9e7c75c56..69fc622cb 100644 --- a/posthog/ai/evaluations/_client.py +++ b/posthog/ai/evaluations/_client.py @@ -23,6 +23,7 @@ _timestamp, _uuid, ) +from ._tags import _response_tags, _tag_names from ._transport import AsyncTransport, SyncTransport from ._types import ( BulkUploadError, @@ -38,6 +39,20 @@ ) +def _experiment_tags(data: dict[str, Any], identity: str) -> tuple[str, ...]: + try: + if _uuid(data["id"]) != identity: + raise ValueError("Mismatched experiment ID.") + return _response_tags(data["tags"]) + except (KeyError, TypeError, ValueError): + raise EvaluationAPIError( + code="invalid_response", + detail="The experiment API returned invalid tag metadata.", + response=data, + persistence="unknown", + ) from None + + def _experiment_body(name: str, options: ExperimentOptions) -> bytes: allowed = set(ExperimentOptions.__annotations__) if set(options) - allowed: @@ -179,6 +194,26 @@ def submission(self) -> dict[str, Any] | None: """Copy of original creation fields; unavailable on a resumed handle.""" return None if self._submission is None else json.loads(self._submission) + def get_tags(self) -> tuple[str, ...]: + """Fetch current tags using a personal key with ``evaluation:read``.""" + with self._lock: + data = self._transport.request("GET", self._path) + return _experiment_tags(data, self.id) + + def set_tags(self, tags: Sequence[str]) -> tuple[str, ...]: + """Replace tags and return the server's normalized names; [] clears them. + + Requires a personal key with ``evaluation:write``. Tags can change after + completion and are separate from the immutable creation ``submission``. + Updates are not retried automatically: inspect tags after a lost response. + """ + body = _encode({"tags": _tag_names(tags)}) + with self._lock: + data = self._transport.request( + "PATCH", self._path, body=body, retry_safe=False + ) + return _experiment_tags(data, self.id) + def upload_result( self, *, @@ -289,6 +324,21 @@ def submission(self) -> dict[str, Any] | None: """Copy of original creation fields; unavailable on a resumed handle.""" return None if self._submission is None else json.loads(self._submission) + async def get_tags(self) -> tuple[str, ...]: + """Fetch current tags. See Experiment.get_tags for key requirements.""" + async with self._lock: + data = await self._transport.request("GET", self._path) + return _experiment_tags(data, self.id) + + async def set_tags(self, tags: Sequence[str]) -> tuple[str, ...]: + """Replace tags. See Experiment.set_tags for permissions and recovery.""" + body = _encode({"tags": _tag_names(tags)}) + async with self._lock: + data = await self._transport.request( + "PATCH", self._path, body=body, retry_safe=False + ) + return _experiment_tags(data, self.id) + async def upload_result( self, *, diff --git a/posthog/ai/evaluations/_scorer_types.py b/posthog/ai/evaluations/_scorer_types.py index 6dd204541..e7aedd95b 100644 --- a/posthog/ai/evaluations/_scorer_types.py +++ b/posthog/ai/evaluations/_scorer_types.py @@ -96,6 +96,7 @@ class Scorer(Generic[_ConfigT]): Read ``current_version_id`` once to pin the version for an experiment. Names are not unique; use ``id`` for subsequent management operations. Configuration dictionaries are local snapshots, not live server state. + ``tags`` contains normalized tag names and is independent of versions. """ id: str @@ -110,6 +111,7 @@ class Scorer(Generic[_ConfigT]): updated_at: datetime created_by: dict[str, Any] | None team: int + tags: tuple[str, ...] = () @dataclass(frozen=True) diff --git a/posthog/ai/evaluations/_scorers.py b/posthog/ai/evaluations/_scorers.py index 2c5dc3d10..1d9e15483 100644 --- a/posthog/ai/evaluations/_scorers.py +++ b/posthog/ai/evaluations/_scorers.py @@ -5,7 +5,7 @@ import copy import json from datetime import datetime -from typing import Any, Callable, Literal, TypeVar, cast, overload +from typing import Any, Callable, Literal, Sequence, TypeVar, cast, overload from urllib.parse import parse_qs, urlsplit from uuid import UUID @@ -22,6 +22,7 @@ ScorerVersion, ScorerVersionPage, ) +from ._tags import _response_tags, _tag_names from ._transport import AsyncTransport, SyncTransport @@ -100,6 +101,7 @@ def _scorer(data: dict[str, Any]) -> Scorer[ScorerConfig]: updated_at=_timestamp(data["updated_at"]), created_by=None if created_by is None else _mapping(created_by), team=_integer(data["team"], minimum=1), + tags=_response_tags(data.get("tags", [])), ) @@ -176,6 +178,7 @@ def _create_body( kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted, + tags: Sequence[str] | _Omitted, ) -> bytes: data: dict[str, Any] = { "name": name, @@ -184,6 +187,8 @@ def _create_body( } if not isinstance(description, _Omitted): data["description"] = description + if not isinstance(tags, _Omitted): + data["tags"] = _tag_names(tags) return _encode(data) @@ -191,8 +196,9 @@ def _metadata( name: str | _Omitted, description: str | None | _Omitted, archived: bool | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> dict[str, Any]: - return { + data: dict[str, Any] = { key: value for key, value in { "name": name, @@ -201,6 +207,9 @@ def _metadata( }.items() if not isinstance(value, _Omitted) } + if not isinstance(tags, _Omitted): + data["tags"] = _tag_names(tags) + return data def _version_body( @@ -223,7 +232,11 @@ def _list_params( kind: ScorerKind | None, archived: bool | None, order_by: ScorerOrder | None, + tags: Sequence[str] | None, + tag_match: Literal["any", "all"], ) -> dict[str, str | int]: + if tag_match not in ("any", "all"): + raise ValueError("tag_match must be any or all.") params: dict[str, str | int] = { "limit": _integer(limit, minimum=1), "offset": _integer(offset), @@ -238,6 +251,11 @@ def _list_params( params["archived"] = "true" if archived else "false" if order_by is not None: params["order_by"] = order_by + if tags is not None: + params["tags"] = json.dumps(_tag_names(tags, limit=20), ensure_ascii=False) + params["tag_match"] = tag_match + elif tag_match != "any": + params["tag_match"] = tag_match return params @@ -273,6 +291,7 @@ def create( kind: Literal["boolean"], config: BooleanScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[BooleanScorerConfig]: ... @overload @@ -283,6 +302,7 @@ def create( kind: Literal["numeric"], config: NumericScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[NumericScorerConfig]: ... @overload @@ -293,6 +313,7 @@ def create( kind: Literal["categorical"], config: CategoricalScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[CategoricalScorerConfig]: ... def create( @@ -302,14 +323,18 @@ def create( kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[ScorerConfig]: - """Create an active scorer and its first immutable configuration version.""" + """Create a scorer and its first version, optionally assigning tags. + + Tag names are trimmed, lowercased, deduplicated, and sorted by the server. + """ return _parse( _scorer, self._transport.request( "POST", self._base, - body=_create_body(name, kind, config, description), + body=_create_body(name, kind, config, description, tags), retry_safe=False, ), ) @@ -327,18 +352,24 @@ def list( kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None, + tags: Sequence[str] | None = None, + tag_match: Literal["any", "all"] = "any", ) -> ScorerPage: """Fetch one page. Omit ``archived`` to list active scorers. Keep the same filters and pass the returned ``next_offset`` to continue. Search matches names and descriptions; scorer names are not unique. + ``tags`` accepts up to 20 names. ``tag_match`` matches any (default) or + all selected tags; an empty sequence disables tag filtering. """ return _parse( _scorer_page, self._transport.request( "GET", self._base, - params=_list_params(limit, offset, search, kind, archived, order_by), + params=_list_params( + limit, offset, search, kind, archived, order_by, tags, tag_match + ), ), ) @@ -349,17 +380,20 @@ def update( name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[ScorerConfig]: """Update metadata. Use ``create_version`` to change configuration. Omitted fields are preserved. An explicit null description clears it. + ``tags`` replaces the current tags; pass [] to clear them. Tag changes + do not create a scorer version. """ return _parse( _scorer, self._transport.request( "PATCH", self._path(scorer_id), - body=_encode(_metadata(name, description, archived)), + body=_encode(_metadata(name, description, archived, tags)), retry_safe=False, ), ) @@ -435,6 +469,7 @@ async def create( kind: Literal["boolean"], config: BooleanScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[BooleanScorerConfig]: ... @overload @@ -445,6 +480,7 @@ async def create( kind: Literal["numeric"], config: NumericScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[NumericScorerConfig]: ... @overload @@ -455,6 +491,7 @@ async def create( kind: Literal["categorical"], config: CategoricalScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[CategoricalScorerConfig]: ... async def create( @@ -464,14 +501,15 @@ async def create( kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[ScorerConfig]: - """Create an active scorer and its first version; never retry mutations.""" + """Create a scorer with optional tags. See Scorers.create.""" return _parse( _scorer, await self._transport.request( "POST", self._base, - body=_create_body(name, kind, config, description), + body=_create_body(name, kind, config, description, tags), retry_safe=False, ), ) @@ -491,14 +529,18 @@ async def list( kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None, + tags: Sequence[str] | None = None, + tag_match: Literal["any", "all"] = "any", ) -> ScorerPage: - """Fetch one page; preserve filters and use ``next_offset`` to continue.""" + """Fetch one page with optional tag filters. See Scorers.list.""" return _parse( _scorer_page, await self._transport.request( "GET", self._base, - params=_list_params(limit, offset, search, kind, archived, order_by), + params=_list_params( + limit, offset, search, kind, archived, order_by, tags, tag_match + ), ), ) @@ -509,14 +551,15 @@ async def update( name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED, + tags: Sequence[str] | _Omitted = _OMITTED, ) -> Scorer[ScorerConfig]: - """Update metadata; omission preserves values and null clears description.""" + """Update metadata, including replacement tags. See Scorers.update.""" return _parse( _scorer, await self._transport.request( "PATCH", self._path(scorer_id), - body=_encode(_metadata(name, description, archived)), + body=_encode(_metadata(name, description, archived, tags)), retry_safe=False, ), ) diff --git a/posthog/ai/evaluations/_tags.py b/posthog/ai/evaluations/_tags.py new file mode 100644 index 000000000..be1448f70 --- /dev/null +++ b/posthog/ai/evaluations/_tags.py @@ -0,0 +1,28 @@ +"""Shared validation for mutable scorer and experiment tags.""" + +from __future__ import annotations + +from collections.abc import Sequence +from typing import Any + + +def _tag_names(tags: Sequence[str], *, limit: int = 100) -> list[str]: + if isinstance(tags, (str, bytes)) or not isinstance(tags, Sequence): + raise ValueError("tags must be a sequence of strings.") + if len(tags) > limit: + raise ValueError(f"tags must contain at most {limit} names.") + names = list(tags) + for name in names: + if not isinstance(name, str) or not name.strip() or len(name.strip()) > 255: + raise ValueError( + "Each tag must be a nonblank string of at most 255 characters." + ) + # The server trims, lowercases, deduplicates, and sorts names. Preserve the + # caller's spelling on the wire and return the server's canonical response. + return names + + +def _response_tags(value: Any) -> tuple[str, ...]: + if not isinstance(value, list) or any(not isinstance(tag, str) for tag in value): + raise ValueError("Expected a list of tag names.") + return tuple(value) diff --git a/posthog/test/ai/test_evaluations.py b/posthog/test/ai/test_evaluations.py index f6f2f96f9..b2e76d0eb 100644 --- a/posthog/test/ai/test_evaluations.py +++ b/posthog/test/ai/test_evaluations.py @@ -114,6 +114,101 @@ def result(item=None, **kwargs): ) +def test_experiment_tags_are_separate_from_creation_and_lifecycle_receipts(client): + evaluations, transport = client + experiment = invoke(evaluations.create_experiment, name="Tagged run") + invoke(experiment.complete) + submission, receipt = experiment.submission, experiment.receipt + transport.request.reset_mock() + transport.request.side_effect = None + response = { + "id": experiment.id, + "status": "completed", + "tags": ["production", "quality"], + } + transport.request.return_value = response + tags = invoke(experiment.set_tags, [" Quality ", "production", "Quality"]) + assert tags == ("production", "quality") + transport.request.assert_called_once_with( + "PATCH", + BASE + experiment.id + "/", + body=b'{"tags":[" Quality ","production","Quality"]}', + retry_safe=False, + ) + response["tags"].append("later") + assert tags == ("production", "quality") + assert experiment.receipt is receipt + assert experiment.submission == submission + assert "tags" not in experiment.submission + + response["tags"] = [] + assert invoke(experiment.set_tags, ()) == () + assert json.loads(transport.request.call_args.kwargs["body"]) == {"tags": []} + assert invoke(experiment.get_tags) == () + transport.request.assert_called_with("GET", BASE + experiment.id + "/") + + +def test_resumed_experiment_can_fetch_tags(client): + evaluations, transport = client + experiment = evaluations.resume_experiment(EXPERIMENT_ID) + transport.request.assert_not_called() + transport.request.side_effect = None + transport.request.return_value = {"id": EXPERIMENT_ID, "tags": ["quality"]} + assert invoke(experiment.get_tags) == ("quality",) + assert experiment.receipt is None + assert experiment.submission is None + + +@pytest.mark.parametrize( + "tags", [None, "quality", {"quality"}, [1], [""], [" "], ["x" * 256], ["q"] * 101] +) +def test_invalid_experiment_tags_are_rejected_before_io(client, tags): + evaluations, transport = client + experiment = evaluations.resume_experiment(EXPERIMENT_ID) + with pytest.raises(ValueError): + invoke(experiment.set_tags, tags) + transport.request.assert_not_called() + + +@pytest.mark.parametrize("operation", ["get_tags", "set_tags"]) +@pytest.mark.parametrize( + "response", + [ + {"id": EXPERIMENT_ID}, + {"id": EXPERIMENT_ID, "tags": None}, + {"id": EXPERIMENT_ID, "tags": "quality"}, + {"id": EXPERIMENT_ID, "tags": [1]}, + {"tags": []}, + {"id": VERSION_ID, "tags": []}, + ], +) +def test_malformed_experiment_tag_responses_are_not_acknowledged( + client, operation, response +): + evaluations, transport = client + experiment = evaluations.resume_experiment(EXPERIMENT_ID) + transport.request.side_effect = None + transport.request.return_value = response + with pytest.raises(EvaluationAPIError) as caught: + invoke( + getattr(experiment, operation), *([[]] if operation == "set_tags" else []) + ) + assert caught.value.code == "invalid_response" + assert caught.value.persistence == "unknown" + assert caught.value.response == response + + +def test_experiment_tag_permission_error_is_preserved(client): + evaluations, transport = client + experiment = evaluations.resume_experiment(EXPERIMENT_ID) + error = EvaluationAPIError(status=403, persistence="rejected") + transport.request.side_effect = error + with pytest.raises(EvaluationAPIError) as caught: + invoke(experiment.set_tags, ["quality"]) + assert caught.value is error + transport.request.assert_called_once() + + def test_create_upload_and_explicit_completion(client): evaluations, transport = client experiment = invoke( diff --git a/posthog/test/ai/test_evaluations_scorers.py b/posthog/test/ai/test_evaluations_scorers.py index 128834c0f..9fa40e918 100644 --- a/posthog/test/ai/test_evaluations_scorers.py +++ b/posthog/test/ai/test_evaluations_scorers.py @@ -174,6 +174,98 @@ def test_metadata_update_preserves_omission_null_and_false(scorers): assert json.loads(transport.request.call_args.kwargs["body"]) == {"name": "Renamed"} +@pytest.mark.parametrize("tags", [[" Quality ", "production", "Quality"], (), []]) +@pytest.mark.parametrize("operation", ["create", "update"]) +def test_tags_are_mutable_metadata_with_normalized_response(scorers, tags, operation): + namespace, transport = scorers + normalized = sorted({tag.strip().lower() for tag in tags}) + transport.request.return_value = scorer_response(tags=normalized) + if operation == "create": + scorer = invoke( + namespace.create, name="Quality", kind="numeric", config={}, tags=tags + ) + else: + scorer = invoke(namespace.update, SCORER_ID, tags=tags) + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "tags": list(tags) + } + assert json.loads(transport.request.call_args.kwargs["body"])["tags"] == list(tags) + assert transport.request.call_args.kwargs["retry_safe"] is False + assert scorer.tags == tuple(normalized) + assert scorer.current_version_id == VERSION_ID + normalized.append("later") + assert "later" not in scorer.tags + transport.request.assert_called_once() + + +def test_scorer_tags_are_optional_for_older_servers(scorers): + namespace, _ = scorers + assert invoke(namespace.get, SCORER_ID).tags == () + + +@pytest.mark.parametrize("tags", [None, "quality", [None], [1], {}]) +def test_invalid_scorer_response_tags_raise(scorers, tags): + namespace, transport = scorers + transport.request.return_value = scorer_response(tags=tags) + with pytest.raises(EvaluationAPIError) as caught: + invoke(namespace.get, SCORER_ID) + assert caught.value.code == "invalid_response" + assert caught.value.persistence == "unknown" + + +@pytest.mark.parametrize("tag_match", ["any", "all"]) +@pytest.mark.parametrize("tags", [[], ("quality", 'a,b"c', "品質")]) +def test_scorer_list_tag_filters_use_json_and_preserve_other_filters( + scorers, tags, tag_match +): + namespace, transport = scorers + transport.request.return_value = { + "count": 1, + "next": None, + "previous": None, + "results": [scorer_response(tags=["quality"])], + } + page = invoke( + namespace.list, tags=tags, tag_match=tag_match, offset=3, search="score" + ) + params = transport.request.call_args.kwargs["params"] + assert json.loads(params["tags"]) == list(tags) + assert params["tag_match"] == tag_match + assert params["offset"] == 3 + assert params["search"] == "score" + assert page.results[0].tags == ("quality",) + + +@pytest.mark.parametrize("operation", ["create", "update", "list"]) +@pytest.mark.parametrize( + "tags", ["quality", {"quality": True}, [1], [None], [" "], ["x" * 256]] +) +def test_invalid_tag_names_fail_before_scorer_request(scorers, tags, operation): + namespace, transport = scorers + with pytest.raises(ValueError): + if operation == "create": + invoke(namespace.create, name="Score", kind="numeric", config={}, tags=tags) + elif operation == "update": + invoke(namespace.update, SCORER_ID, tags=tags) + else: + invoke(namespace.list, tags=tags) + transport.request.assert_not_called() + + +def test_tag_count_limits_and_null_writes_are_rejected(scorers): + namespace, transport = scorers + for tags in (None, ["quality"] * 101): + with pytest.raises(ValueError): + invoke(namespace.create, name="Score", kind="numeric", config={}, tags=tags) + with pytest.raises(ValueError): + invoke(namespace.update, SCORER_ID, tags=tags) + with pytest.raises(ValueError): + invoke(namespace.list, tags=["quality"] * 21) + with pytest.raises(ValueError): + invoke(namespace.list, tag_match="invalid") + transport.request.assert_not_called() + + def test_version_bump_preserves_configuration_and_concurrency_guard(scorers): namespace, transport = scorers config = NumericScorerConfig(min=0, max=1) diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index 55c54fa34..d62d611c5 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -472,6 +472,7 @@ attribute posthog.ai.evaluations.Scorer.description: str attribute posthog.ai.evaluations.Scorer.id: str attribute posthog.ai.evaluations.Scorer.kind: ScorerKind attribute posthog.ai.evaluations.Scorer.name: str +attribute posthog.ai.evaluations.Scorer.tags: tuple[str, ...] = () attribute posthog.ai.evaluations.Scorer.team: int attribute posthog.ai.evaluations.Scorer.updated_at: datetime attribute posthog.ai.evaluations.ScorerConfig = BooleanScorerConfig | NumericScorerConfig | CategoricalScorerConfig @@ -1140,7 +1141,7 @@ class posthog.ai.evaluations.NumericScorerConfig class posthog.ai.evaluations.OfflineEvaluations(*, project_id: int, secret_key: str, host: str | None = None, timeout: float = 15, max_retries: int = 3) class posthog.ai.evaluations.ResultOptions class posthog.ai.evaluations.ResultReceipt(id: str, created: bool, accepted_at: datetime, item_id: str, scorer_version_id: str) -class posthog.ai.evaluations.Scorer(id: str, name: str, description: str, kind: ScorerKind, archived: bool, current_version: int, current_version_id: str, config: _ConfigT, created_at: datetime, updated_at: datetime, created_by: dict[str, Any] | None, team: int) +class posthog.ai.evaluations.Scorer(id: str, name: str, description: str, kind: ScorerKind, archived: bool, current_version: int, current_version_id: str, config: _ConfigT, created_at: datetime, updated_at: datetime, created_by: dict[str, Any] | None, team: int, tags: tuple[str, ...] = ()) class posthog.ai.evaluations.ScorerPage(count: int, results: tuple[Scorer[ScorerConfig], ...], next: str | None, previous: str | None, next_offset: int | None) class posthog.ai.evaluations.ScorerVersion(id: str, definition_id: str, version: int, kind: ScorerKind, config: _ConfigT, created_at: datetime, created_by: dict[str, Any] | None) class posthog.ai.evaluations.ScorerVersionPage(count: int, results: tuple[ScorerVersion[ScorerConfig], ...], next_cursor: str | None) @@ -1497,36 +1498,40 @@ method posthog.ai.claude_agent_sdk.client.PostHogClaudeSDKClient.set_permission_ method posthog.ai.claude_agent_sdk.processor.PostHogClaudeAgentProcessor.query(*, prompt: Any, options: Optional[ClaudeAgentOptions] = None, transport: Any = None, posthog_distinct_id: Optional[Union[str, Callable[[ResultMessage], Optional[str]]]] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: Optional[bool] = None, posthog_groups: Optional[Dict[str, Any]] = None) method posthog.ai.evaluations.AsyncExperiment.complete() method posthog.ai.evaluations.AsyncExperiment.fail() +method posthog.ai.evaluations.AsyncExperiment.get_tags() +method posthog.ai.evaluations.AsyncExperiment.set_tags(tags: Sequence[str]) method posthog.ai.evaluations.AsyncExperiment.upload_result(*, item: EvaluationItem | str | UUID, scorer_version_id: str | UUID, **options: Unpack[ResultOptions]) method posthog.ai.evaluations.AsyncExperiment.upload_results(results: Sequence[EvaluationResult]) method posthog.ai.evaluations.AsyncOfflineEvaluations.aclose() method posthog.ai.evaluations.AsyncOfflineEvaluations.create_experiment(*, name: str, **options: Unpack[ExperimentOptions]) method posthog.ai.evaluations.AsyncOfflineEvaluations.resume_experiment(id: str | UUID) -method posthog.ai.evaluations.AsyncScorers.create(*, name: str, kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED) +method posthog.ai.evaluations.AsyncScorers.create(*, name: str, kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED, tags: Sequence[str] | _Omitted = _OMITTED) method posthog.ai.evaluations.AsyncScorers.create_version(scorer_id: str | UUID, *, config: _ConfigT, base_version: int | None = None, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED) method posthog.ai.evaluations.AsyncScorers.get(scorer_id: str | UUID) method posthog.ai.evaluations.AsyncScorers.get_version(scorer_id: str | UUID, version_id: str | UUID) -method posthog.ai.evaluations.AsyncScorers.list(*, limit: int = 100, offset: int = 0, search: str | None = None, kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None) +method posthog.ai.evaluations.AsyncScorers.list(*, limit: int = 100, offset: int = 0, search: str | None = None, kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None, tags: Sequence[str] | None = None, tag_match: Literal['any', 'all'] = 'any') method posthog.ai.evaluations.AsyncScorers.list_versions(scorer_id: str | UUID, *, limit: int = 50, cursor: str | None = None) -method posthog.ai.evaluations.AsyncScorers.update(scorer_id: str | UUID, *, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED) +method posthog.ai.evaluations.AsyncScorers.update(scorer_id: str | UUID, *, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED, tags: Sequence[str] | _Omitted = _OMITTED) method posthog.ai.evaluations.EvaluationItem.from_dict(data: Mapping[str, Any]) method posthog.ai.evaluations.EvaluationItem.to_dict() method posthog.ai.evaluations.EvaluationResult.from_dict(data: Mapping[str, Any], *, item: EvaluationItem | None = None) method posthog.ai.evaluations.EvaluationResult.to_dict() method posthog.ai.evaluations.Experiment.complete() method posthog.ai.evaluations.Experiment.fail() +method posthog.ai.evaluations.Experiment.get_tags() +method posthog.ai.evaluations.Experiment.set_tags(tags: Sequence[str]) method posthog.ai.evaluations.Experiment.upload_result(*, item: EvaluationItem | str | UUID, scorer_version_id: str | UUID, **options: Unpack[ResultOptions]) method posthog.ai.evaluations.Experiment.upload_results(results: Sequence[EvaluationResult]) method posthog.ai.evaluations.OfflineEvaluations.close() method posthog.ai.evaluations.OfflineEvaluations.create_experiment(*, name: str, **options: Unpack[ExperimentOptions]) method posthog.ai.evaluations.OfflineEvaluations.resume_experiment(id: str | UUID) -method posthog.ai.evaluations.Scorers.create(*, name: str, kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED) +method posthog.ai.evaluations.Scorers.create(*, name: str, kind: ScorerKind, config: ScorerConfig, description: str | None | _Omitted = _OMITTED, tags: Sequence[str] | _Omitted = _OMITTED) method posthog.ai.evaluations.Scorers.create_version(scorer_id: str | UUID, *, config: _ConfigT, base_version: int | None = None, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED) method posthog.ai.evaluations.Scorers.get(scorer_id: str | UUID) method posthog.ai.evaluations.Scorers.get_version(scorer_id: str | UUID, version_id: str | UUID) -method posthog.ai.evaluations.Scorers.list(*, limit: int = 100, offset: int = 0, search: str | None = None, kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None) +method posthog.ai.evaluations.Scorers.list(*, limit: int = 100, offset: int = 0, search: str | None = None, kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None, tags: Sequence[str] | None = None, tag_match: Literal['any', 'all'] = 'any') method posthog.ai.evaluations.Scorers.list_versions(scorer_id: str | UUID, *, limit: int = 50, cursor: str | None = None) -method posthog.ai.evaluations.Scorers.update(scorer_id: str | UUID, *, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED) +method posthog.ai.evaluations.Scorers.update(scorer_id: str | UUID, *, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED, tags: Sequence[str] | _Omitted = _OMITTED) method posthog.ai.gemini.gemini.Models.embed_content(model: str, contents, posthog_distinct_id: Optional[str] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: Optional[bool] = None, posthog_groups: Optional[Dict[str, Any]] = None, **kwargs: Any) method posthog.ai.gemini.gemini.Models.generate_content(model: str, contents, posthog_distinct_id: Optional[str] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: Optional[bool] = None, posthog_groups: Optional[Dict[str, Any]] = None, **kwargs: Any) method posthog.ai.gemini.gemini.Models.generate_content_stream(model: str, contents, posthog_distinct_id: Optional[str] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: Optional[bool] = None, posthog_groups: Optional[Dict[str, Any]] = None, **kwargs: Any) From 43c2d8fc072e54fdaf3e268678d2b9e2f4573c87 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:19:42 +0000 Subject: [PATCH 27/70] chore: Release v7.73.0 [skip ci] (cherry picked from commit 81931fa3048df82243d0d63e636a9ceecd1d0148) --- .sampo/changesets/evaluation-tags.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/evaluation-tags.md diff --git a/.sampo/changesets/evaluation-tags.md b/.sampo/changesets/evaluation-tags.md deleted file mode 100644 index ea734ed30..000000000 --- a/.sampo/changesets/evaluation-tags.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -Support tags in synchronous and asynchronous AI observability scorer creation, metadata updates, responses, and list filters. Add `get_tags()` and `set_tags()` to offline experiment handles for reading, replacing, and clearing experiment tags independently of uploads and completion. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index bc04fd642..a4d699e13 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.109 — 2026-10-19 + +### Patch changes + +- Updated dependencies: posthog@7.73.0 + ## 0.1.108 — 2026-10-19 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index f4f2bf83b..a432f35d7 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.108" +version = "0.1.109" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index d86fb82b4..0e79d205b 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.73.0 — 2026-10-19 + +### Minor changes + +- [b086f65](https://github.com/posthog/posthog-python/commit/b086f65437c4904310279646da76321a80294056) Support tags in synchronous and asynchronous AI observability scorer creation, metadata updates, responses, and list filters. Add `get_tags()` and `set_tags()` to offline experiment handles for reading, replacing, and clearing experiment tags independently of uploads and completion. — Thanks @Radu-Raicea! + ## 7.72.0 — 2026-10-19 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index 36a0dbd29..d502f0d3c 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.72.0" +VERSION = "7.73.0" diff --git a/pyproject.toml b/pyproject.toml index 0de5632eb..e8ffdd8d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.72.0" +version = "7.73.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index bd292e4f2..ced24011c 100644 --- a/uv.lock +++ b/uv.lock @@ -2491,7 +2491,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.108" +version = "0.1.109" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2821,7 +2821,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.72.0" +version = "7.73.0" source = { editable = "." } dependencies = [ { name = "distro" }, From babded692c00a9e971521c2e607fc0eeac930105 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:19:47 +0000 Subject: [PATCH 28/70] Update generated references (cherry picked from commit 9e62e0f9c5a7d6a23a419f93c8f016d43faec2db) --- .../posthog-python-references-7.73.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.73.0.json diff --git a/references/posthog-python-references-7.73.0.json b/references/posthog-python-references-7.73.0.json new file mode 100644 index 000000000..9e6844b34 --- /dev/null +++ b/references/posthog-python-references-7.73.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.73.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 05421adfc..9e6844b34 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.72.0", + "version": "7.73.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 994107b1e2e65b729d66051d627251851f8a8b1f Mon Sep 17 00:00:00 2001 From: Sebastian Turner Date: Mon, 19 Oct 2026 15:18:23 -0700 Subject: [PATCH 29/70] fix(flags): accept rediss:// URLs for flag_fallback_cache_url (#1080) Signed-off-by: Sebastian Turner (cherry picked from commit 20dabaa258b810bae3696bcb67b9679c18ef8f25) --- .sampo/changesets/flag-cache-rediss-scheme.md | 5 ++++ posthog/client.py | 5 ++-- posthog/test/test_client.py | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 .sampo/changesets/flag-cache-rediss-scheme.md diff --git a/.sampo/changesets/flag-cache-rediss-scheme.md b/.sampo/changesets/flag-cache-rediss-scheme.md new file mode 100644 index 000000000..92e5490e1 --- /dev/null +++ b/.sampo/changesets/flag-cache-rediss-scheme.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Accept rediss:// URLs in flag_fallback_cache_url so the flag fallback cache can use Redis over TLS. diff --git a/posthog/client.py b/posthog/client.py index 557d708b2..217478768 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -5008,6 +5008,7 @@ def _initialize_flag_cache(self, cache_url): - "memory://local/?ttl=300&size=10000": Memory cache with TTL and size - "redis://localhost:6379/0/?ttl=300": Redis cache with TTL - "redis://username:password@host:port/?ttl=300": Redis with auth + - "rediss://username:password@host:port/?ttl=300": Redis over TLS Example usage: # Memory cache @@ -5043,7 +5044,7 @@ def _initialize_flag_cache(self, cache_url): size = int(query_params.get("size", [10000])[0]) return FlagCache(size, ttl) - elif scheme == "redis": + elif scheme in ("redis", "rediss"): try: # Not worth importing redis if we're not using it import redis @@ -5076,7 +5077,7 @@ def _initialize_flag_cache(self, cache_url): return None else: raise ValueError( - f"Unknown cache URL scheme: {scheme}. Supported schemes: memory, redis" + f"Unknown cache URL scheme: {scheme}. Supported schemes: memory, redis, rediss" ) except Exception as e: diff --git a/posthog/test/test_client.py b/posthog/test/test_client.py index fda6a5290..b7fb301aa 100644 --- a/posthog/test/test_client.py +++ b/posthog/test/test_client.py @@ -31,6 +31,7 @@ from posthog.test.logging_helpers import capture_message_only_logs from posthog.test.test_utils import FAKE_TEST_API_KEY from posthog.types import FeatureFlag, FeatureFlagResult, LegacyFlagMetadata +from posthog.utils import RedisFlagCache from posthog.version import VERSION from posthog.contexts import tag from posthog.test.capture_helpers import patch_capture_send, sent_batch, sent_events @@ -2762,6 +2763,32 @@ def test_shutdown_clears_feature_flag_called_dedupe_cache(self): self.assertEqual(len(client.distinct_ids_feature_flags_reported), 0) + @parameterized.expand( + [ + ("redis://localhost:6379/0/?ttl=120", "redis://localhost:6379/0/"), + ( + "rediss://user:secret@cache.example.com:6380/1?ttl=120", + "rediss://user:secret@cache.example.com:6380/1", + ), + ] + ) + def test_flag_fallback_cache_url_accepts_redis_schemes( + self, cache_url, expected_redis_url + ): + fake_redis = mock.Mock() + with mock.patch.dict(sys.modules, {"redis": fake_redis}): + client = Client( + FAKE_TEST_API_KEY, + send=False, + thread=0, + flag_fallback_cache_url=cache_url, + ) + + fake_redis.from_url.assert_called_once_with(expected_redis_url) + self.assertIsInstance(client.flag_cache, RedisFlagCache) + self.assertEqual(client.flag_cache.default_ttl, 120) + client.shutdown() + def test_shutdown_flushes_without_timeout(self): client = Client(FAKE_TEST_API_KEY, flush_interval=0.01) From 2dcdd32804dcfce9fcbfc3f75a003e033b5fe7a3 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 11:52:55 +0000 Subject: [PATCH 30/70] chore: Release v7.73.1 [skip ci] (cherry picked from commit 223b592a9666b8c28f6bd90883126ced513d4195) --- .sampo/changesets/flag-cache-rediss-scheme.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/flag-cache-rediss-scheme.md diff --git a/.sampo/changesets/flag-cache-rediss-scheme.md b/.sampo/changesets/flag-cache-rediss-scheme.md deleted file mode 100644 index 92e5490e1..000000000 --- a/.sampo/changesets/flag-cache-rediss-scheme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Accept rediss:// URLs in flag_fallback_cache_url so the flag fallback cache can use Redis over TLS. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index a4d699e13..8b582d72a 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.110 — 2026-10-20 + +### Patch changes + +- Updated dependencies: posthog@7.73.1 + ## 0.1.109 — 2026-10-19 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index a432f35d7..d1203da8f 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.109" +version = "0.1.110" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 0e79d205b..9629faa88 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.73.1 — 2026-10-20 + +### Patch changes + +- [20dabaa](https://github.com/posthog/posthog-python/commit/20dabaa258b810bae3696bcb67b9679c18ef8f25) Accept rediss:// URLs in flag_fallback_cache_url so the flag fallback cache can use Redis over TLS. — Thanks @auraseb for your first contribution 🎉! + ## 7.73.0 — 2026-10-19 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index d502f0d3c..ab107779f 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.73.0" +VERSION = "7.73.1" diff --git a/pyproject.toml b/pyproject.toml index e8ffdd8d1..3d645461c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.73.0" +version = "7.73.1" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index ced24011c..1013796f0 100644 --- a/uv.lock +++ b/uv.lock @@ -2491,7 +2491,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.109" +version = "0.1.110" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2821,7 +2821,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.0" +version = "7.73.1" source = { editable = "." } dependencies = [ { name = "distro" }, From 6efcc7f3aee34dc41a6c53760dbe3ee44163d698 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 11:53:01 +0000 Subject: [PATCH 31/70] Update generated references (cherry picked from commit e9e0830aece3d22871fca082b6143cc2f0265e5c) --- .../posthog-python-references-7.73.1.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.73.1.json diff --git a/references/posthog-python-references-7.73.1.json b/references/posthog-python-references-7.73.1.json new file mode 100644 index 000000000..9c588f586 --- /dev/null +++ b/references/posthog-python-references-7.73.1.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.73.1", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 9e6844b34..9c588f586 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.73.0", + "version": "7.73.1", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 36339cf449a43a59dae206925c2fe3bf3b114d7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 12:15:58 -0400 Subject: [PATCH 32/70] chore(deps): bump aiohttp from 3.14.3 to 3.14.4 (#1086) --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 305dee3ab53afe20482295690dcf3d978a574b67) --- uv.lock | 513 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 303 insertions(+), 210 deletions(-) diff --git a/uv.lock b/uv.lock index 1013796f0..e5bcc9f99 100644 --- a/uv.lock +++ b/uv.lock @@ -67,7 +67,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -80,126 +80,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -4502,101 +4544,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.20.1" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, - { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, - { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, - { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, - { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, - { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, - { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, - { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, - { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, - { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, - { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, - { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, - { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, - { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, - { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, - { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, - { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, - { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, - { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, - { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, - { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, - { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, - { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, - { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, - { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, - { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, - { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, - { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, - { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, - { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, - { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, - { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, - { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, - { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, - { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, - { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, - { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, - { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, - { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, - { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, - { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, - { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, - { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, - { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, - { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, - { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, - { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, - { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, - { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, - { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, - { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, - { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, - { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, - { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, - { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, - { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, - { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, - { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, - { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, - { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, - { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, - { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, - { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, - { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, - { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, - { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, - { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, - { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, - { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, - { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, - { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, - { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, - { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, - { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, - { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, - { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, - { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, - { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, - { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, - { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] From 85fdb91b994bcce218977e90afaaa815f54a259d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 12:16:04 -0400 Subject: [PATCH 33/70] chore(deps): bump the uv group across 7 directories with 1 update (#1087) --- updated-dependencies: - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv - dependency-name: aiohttp dependency-version: 3.14.4 dependency-type: indirect dependency-group: uv ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit 1b865499fc0e51a44c8a6d32f5a953241444bb45) --- examples/example-ai-crewai/uv.lock | 554 ++++++++++--------- examples/example-ai-dspy/uv.lock | 554 ++++++++++--------- examples/example-ai-instructor/uv.lock | 554 ++++++++++--------- examples/example-ai-litellm/uv.lock | 556 +++++++++++--------- examples/example-ai-llamaindex/uv.lock | 556 +++++++++++--------- examples/example-ai-pydantic-ai/uv.lock | 556 +++++++++++--------- examples/example-ai-semantic-kernel/uv.lock | 556 +++++++++++--------- 7 files changed, 2126 insertions(+), 1760 deletions(-) diff --git a/examples/example-ai-crewai/uv.lock b/examples/example-ai-crewai/uv.lock index 2ab5e826d..a7fb05dfa 100644 --- a/examples/example-ai-crewai/uv.lock +++ b/examples/example-ai-crewai/uv.lock @@ -24,7 +24,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -37,126 +37,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -4171,142 +4213,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-dspy/uv.lock b/examples/example-ai-dspy/uv.lock index a5c3d042c..a3eefa6a3 100644 --- a/examples/example-ai-dspy/uv.lock +++ b/examples/example-ai-dspy/uv.lock @@ -21,7 +21,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -34,126 +34,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -2700,142 +2742,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-instructor/uv.lock b/examples/example-ai-instructor/uv.lock index b813097c3..21bc1548d 100644 --- a/examples/example-ai-instructor/uv.lock +++ b/examples/example-ai-instructor/uv.lock @@ -17,7 +17,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -30,126 +30,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -1172,7 +1214,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.63.0" +version = "7.73.0" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -1196,7 +1238,9 @@ requires-dist = [ { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -1704,142 +1748,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-litellm/uv.lock b/examples/example-ai-litellm/uv.lock index 5c9ae49f0..bfa9da428 100644 --- a/examples/example-ai-litellm/uv.lock +++ b/examples/example-ai-litellm/uv.lock @@ -17,7 +17,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -30,126 +30,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -1502,11 +1544,11 @@ wheels = [ [[package]] name = "python-dotenv" -version = "1.2.3" +version = "1.2.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/53/ed9d74092561d4b01a2ef1349d52cdbc135e526c245f366b089cfca6de49/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35", size = 58945, upload-time = "2026-08-16T16:54:54.067Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/26/2fbeedb218a787a5eea551c7532cac4e009f83d689dd2faa0d0353473f86/python_dotenv-1.2.4.tar.gz", hash = "sha256:f0d53e69935a851c0dcc78f3ab7aaccd8cabef0b92382b576b824212902873c0", size = 60824, upload-time = "2026-10-01T05:36:10Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" }, + { url = "https://files.pythonhosted.org/packages/60/d1/38f3a3405989a89ac18390803e70c6ad7c7760da4f9b83cbeca0c44a0c72/python_dotenv-1.2.4-py3-none-any.whl", hash = "sha256:42269a8a5b3fd54ffa6f3d84b18abed50064717576b4ecf03dc4a55d8aa04fdc", size = 23266, upload-time = "2026-10-01T05:36:08.633Z" }, ] [[package]] @@ -2026,142 +2068,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-llamaindex/uv.lock b/examples/example-ai-llamaindex/uv.lock index aaba29e51..1a36872ad 100644 --- a/examples/example-ai-llamaindex/uv.lock +++ b/examples/example-ai-llamaindex/uv.lock @@ -21,7 +21,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -34,126 +34,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -1763,7 +1805,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.2" +version = "7.73.0" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -2593,142 +2635,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-pydantic-ai/uv.lock b/examples/example-ai-pydantic-ai/uv.lock index 0a303b6ab..cac931f92 100644 --- a/examples/example-ai-pydantic-ai/uv.lock +++ b/examples/example-ai-pydantic-ai/uv.lock @@ -48,7 +48,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -61,126 +61,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -2066,7 +2108,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.2" +version = "7.73.0" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -3731,142 +3773,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] diff --git a/examples/example-ai-semantic-kernel/uv.lock b/examples/example-ai-semantic-kernel/uv.lock index 956aa7a39..5f8f0ffc8 100644 --- a/examples/example-ai-semantic-kernel/uv.lock +++ b/examples/example-ai-semantic-kernel/uv.lock @@ -25,7 +25,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.3" +version = "3.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -38,126 +38,168 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, - { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, - { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, - { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, - { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, - { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, - { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, - { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, - { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, - { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, - { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, - { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, - { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, - { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, - { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, - { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, - { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, - { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, - { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, - { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, - { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, - { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, - { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, - { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, - { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, - { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, - { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, - { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, - { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, - { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, - { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, - { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, - { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, - { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, - { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, - { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, - { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, - { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, - { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, - { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, - { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, - { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, - { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, - { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, - { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, - { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, - { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, - { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, - { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, - { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, - { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, - { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, - { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, - { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, - { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, - { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, - { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, - { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, - { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, - { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, - { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, - { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, - { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, - { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, - { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, - { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, - { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, - { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, - { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, - { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, - { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, - { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/93/2f/6a91adaa2dc26877d6ed2f54c0370c8910f019db7d77c5c6a194611e93ea/aiohttp-3.14.4.tar.gz", hash = "sha256:831fc5bd39ec2517851e348f613ddb5447a47cf4b71cb09845af7ad7ed45d8f9", size = 8077839, upload-time = "2026-10-05T17:43:48.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/08/290e4be6e3ed239751c446505c324406a4ae8a82a15009a12a3c550f18d9/aiohttp-3.14.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dea3b3653c1d0d6babd8ce09cb9e5a7776864315d9cfb1c569f926389874a261", size = 834853, upload-time = "2026-10-05T17:37:45.079Z" }, + { url = "https://files.pythonhosted.org/packages/81/81/ed5e04508ba1fcf9a34e0449c78009956e8256f62ebef708e2948594cf94/aiohttp-3.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3099a389e5b5900fc79c6f613015ff3f8fa06a519744e6001cc68a31ba418cac", size = 560957, upload-time = "2026-10-05T17:37:47.497Z" }, + { url = "https://files.pythonhosted.org/packages/90/28/1a91411c53704db0481cc64b0f0c9465aa9d738856abdcaa3a5bbbe18180/aiohttp-3.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70247156fc76e92919f9aacb820556cb30289a54784299a31714d030bb604d84", size = 553475, upload-time = "2026-10-05T17:37:49.099Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2e/1038f3fa8832f9f4bed0f9f751f70dbc52bc4a09c66788f97bbfb0ce3d88/aiohttp-3.14.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf2d2a6ad402797422949f4a200a60d43e3a021695c8a7804aa1d5bbef22652", size = 1845211, upload-time = "2026-10-05T17:37:50.728Z" }, + { url = "https://files.pythonhosted.org/packages/ea/54/e2253f17604c5c1c69a05e3c12400b51cd6a5fb32d7175592114d8c7a470/aiohttp-3.14.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ba835fad8d4b5eaea0d34f9461cf499737a720a5f8bc6768d2f6d98a1d3ba8b5", size = 1814629, upload-time = "2026-10-05T17:37:52.481Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ef/7bd1e45db925376720555d7268c2d642b113105263d37a522e41e1ba3a6c/aiohttp-3.14.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d4415ca5c9c8b24bc2f5733f870d4eab4929e680203559ba60131dd1a27852a", size = 1898528, upload-time = "2026-10-05T17:37:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/26d09668e7e0cadc16027566765aa4ce26e8a41276bad6764848c8b04d11/aiohttp-3.14.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6757e02c2c2b0d7985f57be87cf4a7c5b35708f849e1feaea3f77656ddb9dff", size = 2024385, upload-time = "2026-10-05T17:37:55.626Z" }, + { url = "https://files.pythonhosted.org/packages/73/38/0f1c4aab1cc9518e1bf874e2481e59e541b3e32330b9542e52bb2712f86f/aiohttp-3.14.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2a950bd8418ef54eccf5f9f517f08e37c1adab4bc50a470a0422ee1cc1032e29", size = 1859130, upload-time = "2026-10-05T17:37:57.342Z" }, + { url = "https://files.pythonhosted.org/packages/5f/98/09d5998ba4b5fe9f0cb97d794fab9d1b3d8245c5ec6a5fb84e41a8cec142/aiohttp-3.14.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:34cf6f2fe4fc1d7183e8cc0d8c48bbdda828a740bc372d8278126149714d343c", size = 1714768, upload-time = "2026-10-05T17:37:58.831Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/39d01a74d525d6443084d47ad4aa8c719f44a030149d03566f3761527465/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc0fbe4f79c3b156d754dd062718ffe404c3b31ca878d9d2b88ecdbc72ef8369", size = 1813228, upload-time = "2026-10-05T17:38:00.611Z" }, + { url = "https://files.pythonhosted.org/packages/39/6b/183d7b969bdb7892e86af74147b4afedbb4e03b8cad5006e41aa2034c288/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:d3d50a5a07a2b31a4369b86dd4a3acf3c2577c45091dbd5e884b198dec56480b", size = 1831844, upload-time = "2026-10-05T17:38:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/2c/be/4c6df02b62083efd3f008974cf9016a4afd2023f5a9d2c3fd55499fcbac6/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:de15c46a63f46da881d219e44a04778c40114c756e5575b5ea38143b20eb3713", size = 1868738, upload-time = "2026-10-05T17:38:03.831Z" }, + { url = "https://files.pythonhosted.org/packages/86/21/406be8b0cf1105a35a6a6da16a95796be39b354e29bfca0d1626d822835f/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:caa4c0fc9b25e8c679baac68337e9c00deb6baf6601fe6f07e8511469cc1ceba", size = 1700006, upload-time = "2026-10-05T17:38:05.631Z" }, + { url = "https://files.pythonhosted.org/packages/4e/e6/beac98020ea0885ea1ee3b2ef59ec952405590fe2ccef2fa4ef7614c3c2b/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:3647f8c090632c70abb1e80826e4ee24faea3f895f0283b60e91a0b17aea5e34", size = 1889997, upload-time = "2026-10-05T17:38:07.578Z" }, + { url = "https://files.pythonhosted.org/packages/c4/89/d608dd9571988a529c7fead5bc79ad36b56fd52bad7941f40774acbc87e9/aiohttp-3.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3f3e8030169843fb652a60a3d32c206e03f260198aa398985a48b41cd7e42f0a", size = 1844619, upload-time = "2026-10-05T17:38:10.003Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7d/7f51e6338d2c74b75173ee66fcb50d778d5407c32f34e76ef1c4b25d0d75/aiohttp-3.14.4-cp310-cp310-win32.whl", hash = "sha256:a1205cbdddfca1428129bb6d23e0b292b09e681df951fa828145d83a63ffc0ca", size = 489598, upload-time = "2026-10-05T17:38:11.795Z" }, + { url = "https://files.pythonhosted.org/packages/33/2a/3434e450a4395fc07f3070d6ac24553f0b170b173e949216b1723395028c/aiohttp-3.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:e90980e0454a043f81b435309a089ac5deab883779557eb58d004f33990f61e4", size = 512204, upload-time = "2026-10-05T17:38:13.309Z" }, + { url = "https://files.pythonhosted.org/packages/53/c0/1d89303cf1bea5418268c1cb82b872661bad027e5fd785c2d30d0a31ee6f/aiohttp-3.14.4-cp310-cp310-win_arm64.whl", hash = "sha256:e63eecf9a4b670a24055d5c0486128af16f83b02d9817abd685d3238940f8752", size = 492725, upload-time = "2026-10-05T17:38:14.825Z" }, + { url = "https://files.pythonhosted.org/packages/81/e3/998dc75634ecd2a24f33bab480b57313059d55bcadff8825a46b7c80a8af/aiohttp-3.14.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb0093ca0817019d539f0d27bdf98e823944e05bb7efd9d2337a45b92e4d1b06", size = 832892, upload-time = "2026-10-05T17:38:16.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/c9/9bacc26397854440d169f70ae00ea51721f504611d3a64cf043643792c32/aiohttp-3.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f482dc9c8309801b4259dd218609d3dae0a7bcdedeac56d90500eabaa0c23465", size = 559893, upload-time = "2026-10-05T17:38:18.74Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/90c5856014328a8b1e9a753de794edea282182b776ff65f0602ad4ffa520/aiohttp-3.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa800bb7c1d00e166493931f2ddacb982db913292503dc2f4884db1f2bc5f105", size = 552850, upload-time = "2026-10-05T17:38:20.385Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/e71c29ce6daa78fcee0feb1992f0fdc408f09f42c3311b1f1c68c36f16ea/aiohttp-3.14.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d90e4dae71b26597f6d1fd12af7d092ae67551edf0e524b73e0687214b79ee33", size = 1928941, upload-time = "2026-10-05T17:38:22.218Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4f/f0f3bebfa521a2ce5fd4302c937701cbc50cd6d908beaa597388639b0b98/aiohttp-3.14.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b681054b8c3b86aa6a0384b6ad7f5cb78dccbabab1f4a3a6793f98ad1378959", size = 1882092, upload-time = "2026-10-05T17:38:24.016Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0d/5df041fd25dceb4f4cafbbee49bb2c1e2d54a91aedecaf03b77cbb404c44/aiohttp-3.14.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dfe80b41bcf8d80d2125fb99a171adeb86db2fcb35c1a68e0226acba0ba7f03", size = 1986051, upload-time = "2026-10-05T17:38:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/1a/07/e95eddafffef7c3a74446f67ac4e477a49cec2c78f2ab6c86d1acfd90d2d/aiohttp-3.14.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:71e4a59c6a8c5a6ae8b0b696c32635913e8f526cc01448762eaf5a3c59df8a4f", size = 2107840, upload-time = "2026-10-05T17:38:28.112Z" }, + { url = "https://files.pythonhosted.org/packages/da/6c/1f83990fea249dcb10f48086726953546efc9199c96b6be7114532ac361f/aiohttp-3.14.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f887c3b7fb3058fc1ccd917f52078540c18d938d12018cb9edd64b6811d20c57", size = 1930721, upload-time = "2026-10-05T17:38:30.046Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/48184a186ea26df4f81dd466144dcab7f9cdd1e131bfee0f0e41278c6f0d/aiohttp-3.14.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0da4525e9ba145a11617d2cd7e44fe1acaf471f9c72a0cad28e72879c1020fbb", size = 1774508, upload-time = "2026-10-05T17:38:31.8Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ef/a9ec758c6d3850453838c31b56d1e4499eb47c80883753a12dcb203f9afa/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f7e8d3c5caa44fdbee3eba1aa1417aa58c74c95d4089fe3c451911117fcbb2f3", size = 1902311, upload-time = "2026-10-05T17:38:33.791Z" }, + { url = "https://files.pythonhosted.org/packages/d6/49/9a2be54900f2dea6e63bbf9628fced604686a2e301130ccde0b1aa2e7e53/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:09092cf906c18c824b6b16881da5a89cc9cfa9b15344e496bcf880e9045bee33", size = 1912107, upload-time = "2026-10-05T17:38:35.614Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2b/151254abfc0fe5cbb8e6c41ad04d52122db0af176fb31dbf3bc44e081bda/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:dfd144837e92264878bba6d3a7ffa8206668b21e87748740afd45d193e48c87e", size = 1960207, upload-time = "2026-10-05T17:38:37.322Z" }, + { url = "https://files.pythonhosted.org/packages/23/99/92c8dce336ac5784755a3144623528516f2e3b6b4871d02cad5a0642ae66/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9413cffe4e0d654b9b524f9c99dde8cbdb37e0ed9a2c4edd2e63adbac6b374e8", size = 1760168, upload-time = "2026-10-05T17:38:39.214Z" }, + { url = "https://files.pythonhosted.org/packages/66/3e/f05fd8d1a9595730db8d522882eea76429b9be2ed5337609f7c6e3d9d49c/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f50d719f97ba488dfb8e306cf8c8cc172ff0683ec0af53917b288229aa555ba5", size = 1979946, upload-time = "2026-10-05T17:38:40.927Z" }, + { url = "https://files.pythonhosted.org/packages/b9/14/8941aa73ffceabc2a0eb26878b4f1b2958fb7b5358f97cc49b1c00ed9258/aiohttp-3.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:68ed4824d96b7afec1f3a8d7fba190fe282718041c5772e20298003e1e3e5d66", size = 1923375, upload-time = "2026-10-05T17:38:43.184Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/ef275b63c8bfe0a21e7e8d3ef0e67c4745ed403f1894fe5205057cedd3b9/aiohttp-3.14.4-cp311-cp311-win32.whl", hash = "sha256:d7a41d1427136828e6b11d3f3fd194d4357d5205a5b610be7ae07b1ba52ab974", size = 488414, upload-time = "2026-10-05T17:38:44.978Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0b/21bdd70a1e072222d9dbd96bed4fbed26f7c46c5a20af11b78d32fd049d6/aiohttp-3.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:2efbdb87e79d596325c4eefaef0f4495d701145e882351310ebc538e854dc7a3", size = 512755, upload-time = "2026-10-05T17:38:47.036Z" }, + { url = "https://files.pythonhosted.org/packages/b7/4c/bb324a7d20a9598187bb028ca8d6bcf66c63589c8632420919dd576964ed/aiohttp-3.14.4-cp311-cp311-win_arm64.whl", hash = "sha256:ac6e6f90d9360e460c873f945f11dc8698db0a71fec6612823f1aaaab2c11faa", size = 492960, upload-time = "2026-10-05T17:38:49.006Z" }, + { url = "https://files.pythonhosted.org/packages/22/02/db5935d45347fa8ede56b777930740fb0e72bbb4473ddb6ff8541f6f2afa/aiohttp-3.14.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:55b0b335982b0db7117dff7f6a8e3aad43c4105f9e392ca04f9fc8d958a95cce", size = 817689, upload-time = "2026-10-05T17:38:50.69Z" }, + { url = "https://files.pythonhosted.org/packages/e6/56/f00aa46127e6342f019d567853eeeb932e04fb9b9424b5fb981ad68f4178/aiohttp-3.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d0d8e435582b0d53009dac99e26a3d2be932ed7c9dbfcfc70f3fce1cf943bd5", size = 549599, upload-time = "2026-10-05T17:38:52.525Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/825c09b09962253a2103e4a88c04374ee939c0c8ea31c270daa0308efb07/aiohttp-3.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf734016932d68e1324cfb638cac7a0866a83933a33badf15e836a7e24efb8c0", size = 548132, upload-time = "2026-10-05T17:38:54.629Z" }, + { url = "https://files.pythonhosted.org/packages/40/80/8a1bc8036540fe7cb38219cc5c0aa67d32e9068165725e8199ea8200b08b/aiohttp-3.14.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:322e3d741b3133bcbb981a41d4f9b8ac3545c18de49c662c2b1f4e1c770b98ad", size = 1898485, upload-time = "2026-10-05T17:38:56.439Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fe/65b464d8520ace0d65b4ca69bc9abe175f842c8ce8d1522d363d9669903f/aiohttp-3.14.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:15a3bb5f90a4e515071f3617a45dfe26560beb834a6b6e108cdf4bc9e9719ec3", size = 1875334, upload-time = "2026-10-05T17:38:58.536Z" }, + { url = "https://files.pythonhosted.org/packages/be/51/9c583be502720e927560a8414f4dfb7c7de41945e1a30ccf7003b93c6f85/aiohttp-3.14.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6c044e52df1a466af82cad3518c92ea80cc4ddcfea86966ff083bb34bab29bf4", size = 1937772, upload-time = "2026-10-05T17:39:00.376Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3d/b56512df7ea9cbb5f59099a6b375088dd578356a5a3fb27198ab82e19832/aiohttp-3.14.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d613d7d51bf06fe9a5e3aab86ce06d835bb0ceb1a31ea9e8766df4a403ae62a6", size = 2066220, upload-time = "2026-10-05T17:39:02.54Z" }, + { url = "https://files.pythonhosted.org/packages/11/6c/a7a42701d9ea319140a3d44a24ec72a00b0b46d1b899b26d8a705e65bdd8/aiohttp-3.14.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5e93ab6e6330dce40f5b43996f1fc5f2543296d263a5e4b59ff09e73870b7d8", size = 1922895, upload-time = "2026-10-05T17:39:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/77/04/f8337bd824ca3fe3968d34dc5037ace1c4872551c4621f8266239311d301/aiohttp-3.14.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:20134dc8e68c67e7478124d516449428684c0545b2d3faa575691c8bcbd56678", size = 1712589, upload-time = "2026-10-05T17:39:06.671Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a6/d20e2c940b592d7c4a21690889dbff64fe0ca3facd9190696368694e1488/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f0daef5ef012369dddc391c61f604111424aa9a96313a69fb899018b09d1b01e", size = 1862251, upload-time = "2026-10-05T17:39:08.523Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e4/d50edd5ae5d024b380a8e892e333840bb22967a9eb9c8492108a403f678a/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:19290a108de0718b73bc69b86e788975c6a59855c671ebe2a98a07a6f968328f", size = 1895155, upload-time = "2026-10-05T17:39:10.305Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d3/f36f2931f807ccf8437ec15e8f8bfaa4748d4792639401cc767a866abaa0/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1494877625baeffab669f4a25a09ec4eea721b49e35363081a2a8e4231fe141f", size = 1906623, upload-time = "2026-10-05T17:39:12.411Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0a/94821b711493142bf5e11c27b0d7502776778f7792c77ecc6647357d20c1/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:a779ce4bf099ce4ad2cdfed62f1ca536d435f53237c54ff40172fddada24d1b5", size = 1698932, upload-time = "2026-10-05T17:39:14.446Z" }, + { url = "https://files.pythonhosted.org/packages/d9/76/3d5a0d28362f0053c1c457024749911932481e8fd105fddf8305b1f93c81/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0b4cec9fca876e2d4f4c6cb32b177390132d04618867689f43fefabf3f5c3980", size = 1934528, upload-time = "2026-10-05T17:39:16.354Z" }, + { url = "https://files.pythonhosted.org/packages/a7/51/9784a21dc05d2e0f6acaf864f16db53dab0fbd7b0753cef168601eacb012/aiohttp-3.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:217707313e23aedde9bea67cf8365c7b138b549ae179121ef3f476cf67e3173a", size = 1901984, upload-time = "2026-10-05T17:39:18.299Z" }, + { url = "https://files.pythonhosted.org/packages/44/4f/f98c88703e6d620243aa08473a946ca4e3756b6288690e38f0d9f9c1d007/aiohttp-3.14.4-cp312-cp312-win32.whl", hash = "sha256:18a9fb9a3f6e6e63f4d27f9adeef313a2d3c69a84d31170a844623824e722534", size = 480278, upload-time = "2026-10-05T17:39:20.206Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bc/8555013f84b53e4fdde423131b641af50e822c6d7d9118b24c52b31f6900/aiohttp-3.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:69dcb02d33dfe415d5ee342cc63b7d320efcaf4b761701c7bd7bfb91c715481a", size = 506317, upload-time = "2026-10-05T17:39:22.706Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/ca5bad7bfdaa7ddca053a044a1c7c0d4f3ad9d1f12f96dcab10bfb9c50e7/aiohttp-3.14.4-cp312-cp312-win_arm64.whl", hash = "sha256:d36b0263e7c2fbf1750b9f35d4e7e48b0442d8c45e4a89e3e74168821fb014bb", size = 487683, upload-time = "2026-10-05T17:39:24.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/ec/7fee140da700ec3f5aa5e0fd2319f67be5e86de197e2384d27e5e6209e0e/aiohttp-3.14.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:264b5a7568306590c44ae4a0237ad1715e35d447ea44ebf324e4c8fd9f78f67a", size = 539114, upload-time = "2026-10-05T17:39:26.322Z" }, + { url = "https://files.pythonhosted.org/packages/4e/04/930c01ce9e186e787046433d7dc5b45b188885f8406c14b58435b4431974/aiohttp-3.14.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:17e5d7c7775d8dd8e894c7ef6ebfa26509de36868a9a6c7c4fcfaf6a1bf43d60", size = 553514, upload-time = "2026-10-05T17:39:28.104Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d7/983e3cea81c07e95f35d34da4d1e182b5c05489c49b7560b198a83f0da79/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e91dc8fe9cbd052d16f7f1267e285cf8bbac4d2194bd5741f05ef201c77ed09e", size = 521381, upload-time = "2026-10-05T17:39:30.419Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/80baed11659093883f51245755105557d3253e45bd0b693d70df0059d68b/aiohttp-3.14.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8df6157d31703972aec9e3b93963f039ff06318301e30b007c3e941ff8a7ac42", size = 528347, upload-time = "2026-10-05T17:39:32.344Z" }, + { url = "https://files.pythonhosted.org/packages/c8/18/bfda255c311096c08dab26dc65f3d219f090df37dc5f5f6345f8c3aefc1f/aiohttp-3.14.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:220912b351549dc736c59d104dc443fa615753102bb778a4e98f86e4d94bff6a", size = 539914, upload-time = "2026-10-05T17:39:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/51/fc/3b6ca6117c0c42481d719411fff7b5d3970ebd906543d3dc1ba40fe2462f/aiohttp-3.14.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2efa42b39bb3f524d5eca3760639b584afdd1143a6b047fda29910ffb75e4993", size = 813997, upload-time = "2026-10-05T17:39:36.061Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f6/86e3e02a9712aadc1ae0a1076bb2d1adf3d9addfe5542a28190c8f9b6d9b/aiohttp-3.14.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e7356059c8262d2c1fd95242e2b7b70fbc6eee3135bf470049cbec3e968b5b0", size = 548058, upload-time = "2026-10-05T17:39:38.109Z" }, + { url = "https://files.pythonhosted.org/packages/85/7e/6b9c2e271419d40ca76589613b3c7ab185fd3050a407bd2565b6aa46f695/aiohttp-3.14.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fac247d0cc956d732df1211ac2d8a9999ec8dc1a92a90401de9d52e4ead546f7", size = 545933, upload-time = "2026-10-05T17:39:40.193Z" }, + { url = "https://files.pythonhosted.org/packages/14/fc/33d6e24a5f8ac32423230088c415e2a1c6efee23d902b62f20506631e40b/aiohttp-3.14.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2eb0f8b03b4f2bd154ed8cf7c1a119a1ad04808c258bf58f90138c83b8c6d5", size = 1888265, upload-time = "2026-10-05T17:39:42.182Z" }, + { url = "https://files.pythonhosted.org/packages/8d/e8/2eca1d468d83a514621d1280f9992d08649191db2028c9236b4edfa7c723/aiohttp-3.14.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbe827d27e0e369fd7bb88ceeaa5b46ea006e73e015b9dd77e3723a53162293", size = 1872300, upload-time = "2026-10-05T17:39:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f6/5872983de71b0214acdfb86822f5cca295b39be4832ec589fa224aee0f6c/aiohttp-3.14.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a70387146d03af9f047c629b71aa27d9594b3b31ec4c9c91e1a73d0d8bf38e0e", size = 1926213, upload-time = "2026-10-05T17:39:46.199Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/ebfefa11a546c33c717af63c67868408ecf0b33b23a9d75669af95485407/aiohttp-3.14.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d0934926fc65744e2fdd44ce68b2d79d5ee608a1e23f0596b35dd696519bb7c", size = 2056609, upload-time = "2026-10-05T17:39:48.221Z" }, + { url = "https://files.pythonhosted.org/packages/69/c0/70667e82ec041f4122a17afce711bbcf94a71bec5888b69a49aed8817be2/aiohttp-3.14.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff4b366510c733974adb7a4102c094e4a6308e6f369315a4cf14d2d0a619cf82", size = 1914740, upload-time = "2026-10-05T17:39:50.304Z" }, + { url = "https://files.pythonhosted.org/packages/bf/86/559e9dfea676206b20737d7ccb5b3716bff5e58d2a8d53682e5301724cd1/aiohttp-3.14.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:85fac7c99e0ac3dcbd6ae1c33774e0603bfc732ddb967a6fce4a731103c1888e", size = 1703390, upload-time = "2026-10-05T17:39:52.385Z" }, + { url = "https://files.pythonhosted.org/packages/fc/91/c98897d4cf23e120b2f3980042835cb34c86bbe3c653f3eaacf4bf986349/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef1e9c3b4a2300023a5dc865889ce532cfaf6798ba4ef78fbbefe738a9d23efa", size = 1852642, upload-time = "2026-10-05T17:39:54.391Z" }, + { url = "https://files.pythonhosted.org/packages/14/13/0258f352cb2c236f358a5b57d138e15fa2566e17accc0758d968dbf2ceb6/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:97e65916588be0f952b3307aaa8460c0771fa98dbea2dd27dabc9f5d84d53c3b", size = 1890616, upload-time = "2026-10-05T17:39:56.466Z" }, + { url = "https://files.pythonhosted.org/packages/64/3c/f43e294ce1a06d1234a97bd862c1aa31acfa1a0eea3786c22fd0dc1ea731/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:840775cb39a9424f9edf142133a1192263ac5bd79117ad2a16602cef6a0c1e9d", size = 1896638, upload-time = "2026-10-05T17:39:58.585Z" }, + { url = "https://files.pythonhosted.org/packages/9f/f7/ce1e3a85b73d05037d729d3d32da7d6959b9e433435e9abd46c2fb38410f/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:54f9256430ca040d58affbd551513de13a5cff7d065204fc52b9a1b0af09a049", size = 1693003, upload-time = "2026-10-05T17:40:00.698Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/45eb900d6a9ee046728f5589f3d07f5d78f049b5fb84f48881fa4174d5df/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:6112d5931bf12c776188cab81b82bbb17d86e2e1381f2ade6edc43e6b240f0cb", size = 1927730, upload-time = "2026-10-05T17:40:02.943Z" }, + { url = "https://files.pythonhosted.org/packages/b2/43/a83ff79dc8375953a1f00b808a21c82590f4e68304fecccdcc42a25fb7d8/aiohttp-3.14.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:facc6df39047c4732cbd885bb62e40df20885fcd709fc399e11f81b45ce0fff9", size = 1891177, upload-time = "2026-10-05T17:40:04.989Z" }, + { url = "https://files.pythonhosted.org/packages/5c/ba/fbdc41608d4e2fb6084d960a41b392fa82beb5b126c2466de549b5c67fc8/aiohttp-3.14.4-cp313-cp313-win32.whl", hash = "sha256:7968634fa3a967a2bc0b9aeba1d5a1955501dcd7d0de44b96f7ebfb662797735", size = 479943, upload-time = "2026-10-05T17:40:07.402Z" }, + { url = "https://files.pythonhosted.org/packages/35/51/d75629750e705832fd5cd52516a82943ed58b6e09c30e14830f5d87452fa/aiohttp-3.14.4-cp313-cp313-win_amd64.whl", hash = "sha256:c0a894b0265d139cd4c2c8bd4643822cc289a4a5331e21e810881bd000ffb2dc", size = 506209, upload-time = "2026-10-05T17:40:09.49Z" }, + { url = "https://files.pythonhosted.org/packages/02/64/66452d2ffcc13e5e5ee4ba4a968656fa4a98c29ed5ff0205d4fde02b2943/aiohttp-3.14.4-cp313-cp313-win_arm64.whl", hash = "sha256:da16c3037178e72589d91de59536d271dffc92c2be2b47c38a45538cba54fd29", size = 487163, upload-time = "2026-10-05T17:40:11.526Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fd/b653b1f969e2e949fe4726af7a8043e8ef117f202bed7757ac8564e077a1/aiohttp-3.14.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:749bfc43bb1df71bbe6ed215044d5412d786698fc5771d2037436ca49622f3c9", size = 540738, upload-time = "2026-10-05T17:40:14.109Z" }, + { url = "https://files.pythonhosted.org/packages/90/b5/eea49a0bb697deffac5165d707ec53a24748d6720b3af77a544107b49573/aiohttp-3.14.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:c113e4b489d711f606ca278cd8dc89179746244ea841aa0638b1b134600afad0", size = 554494, upload-time = "2026-10-05T17:40:16.231Z" }, + { url = "https://files.pythonhosted.org/packages/11/ea/cf8f4efbbfa8572d9965cd43b3c6c84c581aa006772e5ce3ab4020027e9b/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:50969522bc7022026a2c7968e67da5c789f6b716b988edac55dc630390efd5df", size = 522653, upload-time = "2026-10-05T17:40:18.879Z" }, + { url = "https://files.pythonhosted.org/packages/a3/24/9f6721f0b52323789cb1041ffc3afa729462d9925607e733a065b6fc5e17/aiohttp-3.14.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:cbf92cd7a1c800cee244558dd5630abb45c1c1093ef7b0d546a99f526ff7a9eb", size = 529697, upload-time = "2026-10-05T17:40:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a4/399debc3c2ca0ab88a08e3082b4c4f62d0f66978af60243c63f2345ef337/aiohttp-3.14.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:fc76be08ff407fba717a769aff04ca1b4bf9ecfdcb5caadef84a563fdbbd146d", size = 540526, upload-time = "2026-10-05T17:40:23.548Z" }, + { url = "https://files.pythonhosted.org/packages/a2/97/90379813b18b795bccdeb3a5a85e9b93ac2c69f9c2a5d0faba59da3ad6d1/aiohttp-3.14.4-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:9b416f995b68a921069e6ec61fa07f2ac3ff033d92e97a69f673af89f5bb954d", size = 818866, upload-time = "2026-10-05T17:40:25.842Z" }, + { url = "https://files.pythonhosted.org/packages/78/70/824fd0dac819652f1df895b3f621a75bf0a3050c30e38d8d2316e34ab821/aiohttp-3.14.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2c9585101cfca10e74a07cc0ef2bdc6d90616e6750926b20456f429d0608f740", size = 549666, upload-time = "2026-10-05T17:40:28.523Z" }, + { url = "https://files.pythonhosted.org/packages/8c/45/eafb2dd200dd2b770ed25a2dc5731c4ba5d58ab3fa8e2e82494bb946808e/aiohttp-3.14.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3c4dcf611b095e7983421f49d01ffbed7ed574891533d606ea115fc23e7c4e90", size = 548961, upload-time = "2026-10-05T17:40:30.613Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/6c733a1c71300293471ac7ef1dffd12b5b4dc9a43c53461224b2b8a7f667/aiohttp-3.14.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f8f61a9b5fa56c58e3441f9dc64137f786232d40fb89127190d0e0f84e1e5865", size = 1883165, upload-time = "2026-10-05T17:40:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/34/885ddbd351679a31141b25e0d1a5e4f67738806e564c858b399709b61239/aiohttp-3.14.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d43e538dfc85b705fd832620d050970ef5613b3869a7169b44a554b9dab9eee9", size = 1844119, upload-time = "2026-10-05T17:40:35.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ef/0a64dac53c11d569851efb3e7eddb43551df72b2c172ebb34cccc93bcd3f/aiohttp-3.14.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4135c4bb4b7682a7633fadc7170ea969d843f83aa7224e70111a20675105c985", size = 1930222, upload-time = "2026-10-05T17:40:37.527Z" }, + { url = "https://files.pythonhosted.org/packages/69/5f/774792ed8f973e0d234fcb06b0f0bc9f29e9a0a0dd847f6418c2904be7d9/aiohttp-3.14.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9055324f156a94fdf6dc9a825ae60f9a2947b88f591ea81ee80826633de62ae7", size = 2038842, upload-time = "2026-10-05T17:40:39.815Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/e00f35581c97656d9e864edaa03292382c620dd1d9c836a4f73a2279acc4/aiohttp-3.14.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb22c8e4b60385a9b414c70c6e8b2d0f4b23ff7fc4bb572ceb58297b228169f1", size = 1887845, upload-time = "2026-10-05T17:40:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2e/07e3eff5b4c1b082a2eaf0ffb508b409b21ea1ddc9fdc57f3eabb51469a1/aiohttp-3.14.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3b6945559a260112742ed58cde2165488d2fc51aeea34afbaa99d9371b43e1b5", size = 1702533, upload-time = "2026-10-05T17:40:44.569Z" }, + { url = "https://files.pythonhosted.org/packages/75/44/816844b7f876e6f8fee4ecb088269fcd92241da712e4814a4d624eda13a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f4078a90b174f15efb2c8725e8720c40dbd3b2cf6350dbc085c964a938d9de7", size = 1849058, upload-time = "2026-10-05T17:40:47.818Z" }, + { url = "https://files.pythonhosted.org/packages/ae/bd/163242e12464a1f3e58a77e28beca949652ddce84abdd5500a91c70a1e0d/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f433c5654e32f72de3ef074d715eb5c7604eb6d28a5c2f3c9e5056f20fe6b306", size = 1854600, upload-time = "2026-10-05T17:40:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/59/5c1ae708a89524eddfd9c727b87cae26b5c50c3c76683b910ac06151ead0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:871035fe79c636b6bc126ed78df37d72b830dfc751612cb4b1040360edf2719f", size = 1896565, upload-time = "2026-10-05T17:40:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/37/45/95300a7de69241fe47d3f838f3fb582c712782e172d447ff650a013ea673/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2617132524f66338f6c1d218cd16081576aefc40df4f2bcba338a99fbf67fec1", size = 1693092, upload-time = "2026-10-05T17:40:54.862Z" }, + { url = "https://files.pythonhosted.org/packages/ff/33/01a8e61d48d0094121092c74125df14c0f8f10ee3149bfe68b6f869409a9/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d8bc326133272deee8ef337581550450e4bb735c0520be893b950a1f5baaf41a", size = 1917073, upload-time = "2026-10-05T17:40:57.656Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d6/1a4f24624cda6686d5b927e26d5d1ae3ebb692faf88e93017fab4b391fd0/aiohttp-3.14.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ec57223e261b7fa9979c12dbce009ca53439be76cac3af27f860d3e4b1d6f7a", size = 1872656, upload-time = "2026-10-05T17:41:00.123Z" }, + { url = "https://files.pythonhosted.org/packages/be/be/ed286fcfa2d22061ae021b568c790123505cd482df35e23023339ecaed96/aiohttp-3.14.4-cp314-cp314-win32.whl", hash = "sha256:7242043e71fc449a19a47d92f4e9fd1e0ae8d3f88488982381f422bf6d651218", size = 485461, upload-time = "2026-10-05T17:41:02.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/74/e040e6f65f4da305777f1adb3023d47401693489e4a337c983b52d2a0a6b/aiohttp-3.14.4-cp314-cp314-win_amd64.whl", hash = "sha256:019587c7b3a44917dd61bcb312fd5c034f341dc9851b83e7b41b65e08b68ca0f", size = 512147, upload-time = "2026-10-05T17:41:04.98Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/bddb33ae15fdd5a68a10a986587aa9916c418a712fdd110d3b3ae9b51407/aiohttp-3.14.4-cp314-cp314-win_arm64.whl", hash = "sha256:60dc71d38db0988f37e78f6ad4a010a2f6355cfac3fff5f130cf5ef2231f3f0d", size = 494685, upload-time = "2026-10-05T17:41:07.366Z" }, + { url = "https://files.pythonhosted.org/packages/22/2e/7b884014b40573f919fc3a528e5028bc37b249e31a93928ba61bdd25c960/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:674f53ab9d2794e2dd767619a3384bf1006f8d075e43c19d449a645f8ff641c2", size = 855696, upload-time = "2026-10-05T17:41:09.514Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e6/b6e2b4f580ab6ae39241bb9182aca60e6e1915cdad0148faaa04db3f366b/aiohttp-3.14.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6d243221f73e5ac546c2ed9255100423e4bc092b08b944f23498e8cf3096c26c", size = 567931, upload-time = "2026-10-05T17:41:11.685Z" }, + { url = "https://files.pythonhosted.org/packages/63/99/ae8e3a1a18adcbf636839d18b3cccc51007836ccdae5209381c5cf82d1ae/aiohttp-3.14.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0daa016eb74e7888ed5f9ceec6eea3158999c1c4a115ef5cbe88baa8d924f94c", size = 567421, upload-time = "2026-10-05T17:41:13.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/38/c5d4bb58be72b967a4090d2deeb38571f8c992852936c51dbbbeae49db1c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70c031a622aa20add05ebd234b90adaf6bf51c1c88cc305ec760721af83308c3", size = 2054173, upload-time = "2026-10-05T17:41:16.098Z" }, + { url = "https://files.pythonhosted.org/packages/eb/87/3c8a9c7670f56d478a75c5bb84b336fb61a67b908e36c30a4a96ed8c8e86/aiohttp-3.14.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7df363fa7c38945a896e12c69af4a1a56cbd4152791d9e41fd0bac396b72de38", size = 1918296, upload-time = "2026-10-05T17:41:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/bd00e499c0a1505b44f5e23b9739034ea9be792ad42537f2894211ba1c07/aiohttp-3.14.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02a508ba5ad91c4d730523584c0adc65882274bba5e37c33bc2f475e37577256", size = 2027513, upload-time = "2026-10-05T17:41:20.874Z" }, + { url = "https://files.pythonhosted.org/packages/23/1d/a3666a7c224f86a881f18d673a8ffdc92fa4c35274fb4361822f8f0dc566/aiohttp-3.14.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0cb3edece6fe6a944eaf97d803b88f606da6bc1600b1894c2969e78ffdc1fc29", size = 2152686, upload-time = "2026-10-05T17:41:23.181Z" }, + { url = "https://files.pythonhosted.org/packages/46/7e/f4204b8c4959c46f6367c182afbbacef08a1b53874281912c52fbd80151c/aiohttp-3.14.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:21ce1223b461bcc5fb389a7204001578f1c0b85c2da60a84d915ebb021294245", size = 2006431, upload-time = "2026-10-05T17:41:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/33/43/091e69d42967cbea833ceb355c5457f8f70748fe08b88c9d91491b3fafb8/aiohttp-3.14.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35d5432f0dc1c8b71307e9112461b52f336da225e344283eec4779222c0a1dff", size = 1789101, upload-time = "2026-10-05T17:41:28.095Z" }, + { url = "https://files.pythonhosted.org/packages/47/7b/b57cbe533c01098c5d30471f057e7c3c19f281122f756acc9c716b636e2c/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6ec364493057c118d08292f7cd60865965c209167d8657b45643a26aef77495", size = 1974472, upload-time = "2026-10-05T17:41:30.499Z" }, + { url = "https://files.pythonhosted.org/packages/9f/44/79acce03611450e4ed8594f96f1cea40d70bc84fb4e918f94d7d9454a4af/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:70492983b7aed9e61bda82fe1ce80bcba9199610886443133783a288638923c0", size = 1956340, upload-time = "2026-10-05T17:41:33.009Z" }, + { url = "https://files.pythonhosted.org/packages/da/bb/36e6cbd6720e3377a02f8709aec6fe80de729ef41e78ba01f13d50363c73/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:a77776673331577147e9d25cd7833a72e8891b47556336cff06ba1569e488b99", size = 1965771, upload-time = "2026-10-05T17:41:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/69/0f/879735ac70ce5e6852916eed51c706a517b205150a8d384f9fa60933a3fc/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:73799000dd6fd5247094fd8e6d3e1eb871e41aab5cc35dff9d9f654cd230bc24", size = 1780297, upload-time = "2026-10-05T17:41:38.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5d/7c030ca5b6baf3b02eccd11afc3d58f0b35e407031d5cc78cae9c24921c0/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:27b370fb532e707e8c96d04fa0c96301fb7dba2d50aaca57f6c456cdfffec5bd", size = 2001374, upload-time = "2026-10-05T17:41:40.888Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/ddacbb8141d727034c51dd192d17749521d5b30b03f84aa034325396089e/aiohttp-3.14.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:884e0d1c707b6217fee3080b9b4029eee7551af788ee761010df19be158414b7", size = 1968531, upload-time = "2026-10-05T17:41:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/3a/08/2214f823701eebc3e57db141faeae76df7bfd415f254cc7c1692258f228d/aiohttp-3.14.4-cp314-cp314t-win32.whl", hash = "sha256:f2e3d34edb151d3e27f93a8338e2da33e2c7261cd4c879ce5f5fe280cc190ea5", size = 504126, upload-time = "2026-10-05T17:41:46.321Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/90e9b6fd23310b4e82d0c0a37b5ecc2944053350473c57533c1da9647235/aiohttp-3.14.4-cp314-cp314t-win_amd64.whl", hash = "sha256:88cf889e51092537fe44adfbff96c2a22d6479d6f92b97b3d413fbfd0a4decf4", size = 531494, upload-time = "2026-10-05T17:41:48.849Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/5b501472c92b9b1dc53742591d6210dccb262962f4721299300d3a9f664b/aiohttp-3.14.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ca450c6d42fda7c0bfaf0e200f32f77c5f2c960a33be1e14d197c84588b7f5f6", size = 510544, upload-time = "2026-10-05T17:41:51.358Z" }, + { url = "https://files.pythonhosted.org/packages/0f/77/ef165a197850573ea07c8d77bf5f4854a1db12fdb20e1cf0b218abf025fc/aiohttp-3.14.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:3b10799df72f66c30935bc661cb89e5ac2918debfc575e350e226fbaa846cbb7", size = 540737, upload-time = "2026-10-05T17:41:53.761Z" }, + { url = "https://files.pythonhosted.org/packages/e6/aa/1663f64d1316b3be9d3f6fafa02b8d888070171a6544cba515e82f3af595/aiohttp-3.14.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:7ffd7f9dd39caccc6b2f68ec0339435ecad2b20f6ea2e2b3de91bbe464ac7137", size = 554600, upload-time = "2026-10-05T17:41:56.183Z" }, + { url = "https://files.pythonhosted.org/packages/98/f7/d4d535855123c1a774a798643e75fdfbac62c047b0c0729d6505d09df444/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:a0a7a227353f7693f73878ad14cd2623cafadd656ababcd20e2adfb7225172ea", size = 523184, upload-time = "2026-10-05T17:41:58.624Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5f/18a8d1cd2958a0b6164b047c18ccb192f2123bb70f1c0a145f6f01f858ad/aiohttp-3.14.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1c43b6af8e4708e8b3812a9ee4f79895207e12d555b7f6d70deb838e0011e12d", size = 530342, upload-time = "2026-10-05T17:42:00.96Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/d1dd2b1fcf8a3192a431375b287a8762ebfd22195ab5b201d3fac30e3a7a/aiohttp-3.14.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:97416b2b997e5e9b817e322b2f0a89b76c54cde22471f51ac17ac15e10901ba0", size = 540629, upload-time = "2026-10-05T17:42:03.324Z" }, + { url = "https://files.pythonhosted.org/packages/37/51/d1868f3459f618f6b68a6ef549d8b3f76aa616fa083298911fd3ae65d6b9/aiohttp-3.14.4-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:ee2a5aa31e507c17841d592364f2148393b17f83bc2766e9211e1eb31ea72a70", size = 819347, upload-time = "2026-10-05T17:42:05.713Z" }, + { url = "https://files.pythonhosted.org/packages/84/e6/53179b721b67e0bd20974d02eca97b5691559e8ce666ba23a65aecda6b7f/aiohttp-3.14.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:5d5d9843c34866e986dd24eef713452609e304550c471320ce7b54b3cfb1391e", size = 549825, upload-time = "2026-10-05T17:42:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/00/0f/d67ddf7a43d4899176954511b6c048328abec1a5df4901f811a3b408a4fc/aiohttp-3.14.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:efcbf93e31b52c21665b6ebc489eb6fdb0dfd86b592edc677b5cffdfa7b11677", size = 549315, upload-time = "2026-10-05T17:42:10.766Z" }, + { url = "https://files.pythonhosted.org/packages/9d/db/42f372c7f8e259505f239cb49db75f23548deaec56d22c68b4866f1c3fe2/aiohttp-3.14.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f1a79977794592dcf6485ed964ec2448db527a1bc0c72ec89663658dad3a739", size = 1892181, upload-time = "2026-10-05T17:42:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/23/0d/8b1900216302a94f69b41bf0786bb992a6e67d703f4698e335c2442db615/aiohttp-3.14.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:515e7ac6d27509dc3ba2c35fb88970b00b9e7b07ee7cc947c8733dcd54ef5def", size = 1883513, upload-time = "2026-10-05T17:42:15.704Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5e/15c014313e567fff931ec4a5f81683cc40251257791fbd607ec37c0dad80/aiohttp-3.14.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:185154ffa3b54765b5de96f464f41cfa476f8815a03854ae5e0fe4d48fb06e9c", size = 1933283, upload-time = "2026-10-05T17:42:18.241Z" }, + { url = "https://files.pythonhosted.org/packages/f5/b3/bf7dc39a450218efb1d5c692bac7dc85ef56da282e889bee594f3267211e/aiohttp-3.14.4-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6aece59f77959628a22cd2ffe48b102cda9611d680e090f204385b3998a1190f", size = 2041054, upload-time = "2026-10-05T17:42:20.728Z" }, + { url = "https://files.pythonhosted.org/packages/b6/03/ffba18d7aaedb5eafac3f41f0c26621ebb0a740bb0115ea2fae1911d902b/aiohttp-3.14.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7205aa6589f1ad1306c6994ff2e1ab5efabacf938f9ffd7682fb225c197b06a", size = 1895494, upload-time = "2026-10-05T17:42:23.518Z" }, + { url = "https://files.pythonhosted.org/packages/45/f4/68123365b86826eee82bdceb7fb4c429204cb3a104d6b7ae44bc6a543fcb/aiohttp-3.14.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f38c7b3ce60d55ac0f2a9fd2edc194789d043fefea15cfb7dcb40b7d5f561146", size = 1714098, upload-time = "2026-10-05T17:42:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/b13c0b214afc571782e8667f3b9e0bbed6843397be90fa35acf2f3ecfbb0/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:b0a1274ee4ee6203c15a341cce87f9f3df8151d5496047b3608bb62bd969cffc", size = 1857111, upload-time = "2026-10-05T17:42:29.169Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7f/4f5d3cee3c23b57119aebba5174962fed0bc493f37f38edab2f5730411b6/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:69ce2407951516f413adf3132b88451eababd710ce631f83c81a9603a3640253", size = 1892123, upload-time = "2026-10-05T17:42:31.786Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2e/5a6a1f014c4e17d58d4e935d0dd64e612f4eaa2f33cca2475b48ca5e3fb5/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:b84d3d057c60eb8e0c2b457a1203e868d82709d3f0c272a4975dfd88c2414939", size = 1898809, upload-time = "2026-10-05T17:42:34.34Z" }, + { url = "https://files.pythonhosted.org/packages/de/f3/d1cca5311a70fcc1c7c2082e02044578a69bcb10686db33a322df9fb849e/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4ecc84f69c9e217984f6877e832e4786a74567432c0bf2b7512919fbdfe18ade", size = 1704814, upload-time = "2026-10-05T17:42:37.047Z" }, + { url = "https://files.pythonhosted.org/packages/0a/cb/cd58eae366148a5b9b1baa233542151154f2b72cd32daa39fd9db97d0c0d/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:878f2d7950238b2b0a8cbb88054444a125f0cfbc77f54c811aca0483132a9be3", size = 1918390, upload-time = "2026-10-05T17:42:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d8/f5e6c4939432734033048ba631503edf4a1e693ee5e261773e169803bbe4/aiohttp-3.14.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:6ff9d3a0e6935f1cb0a6685f9f4b3f0d3e406456d7a434a03cf309b8cd5d7a2e", size = 1878321, upload-time = "2026-10-05T17:42:42.528Z" }, + { url = "https://files.pythonhosted.org/packages/2b/71/462957d6b5d4eb208f78e67745c41480bad2e738aa7caf1d9b07536920c1/aiohttp-3.14.4-cp315-cp315-win32.whl", hash = "sha256:e07dfd7cd360f20be26dc2487ad4c7f21b0b39fdd593e9ebf37d2424ad52defb", size = 485536, upload-time = "2026-10-05T17:42:45.223Z" }, + { url = "https://files.pythonhosted.org/packages/ba/6e/48f59266a8b8c6420894ff59b8e74175252da67df85967b96997e96b7092/aiohttp-3.14.4-cp315-cp315-win_amd64.whl", hash = "sha256:921fc4f1ad549091bfc39cb5e93925b04f307f83517756a3111843851130efce", size = 512087, upload-time = "2026-10-05T17:42:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/25/f5/46263b23cee4f312e28aaabbdec2e074c807700a12c9dfa18beff461f035/aiohttp-3.14.4-cp315-cp315-win_arm64.whl", hash = "sha256:5be8af106f96fd625f6c264fa9faaaa9e0104089684d9015d2fa5b6eba6407c7", size = 494709, upload-time = "2026-10-05T17:42:50.615Z" }, + { url = "https://files.pythonhosted.org/packages/77/8d/e3b1d406c95a8fe436ae2e5f01ee9591196c6c22c44c645b24f20d73eaea/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e69727ec04a4608200ff32ec29478299df7657e2eb78c416ae338d0ca6662596", size = 856014, upload-time = "2026-10-05T17:42:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/5d/fc/e9e78d1097830040bc0a4b8af073379f964064bfa7f0a852d774f96f3168/aiohttp-3.14.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f8b658dd3ef2ebd7708b311ed96ff7cb5edaca001a30018a091504ef492bcb1c", size = 567724, upload-time = "2026-10-05T17:42:56.416Z" }, + { url = "https://files.pythonhosted.org/packages/e6/ad/c813a705a1da1c111c30723b52e1efb67763e9f0b3b54a418cb419616e7a/aiohttp-3.14.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:3749e018123df1205161a73ba96d336e17e9cf6b947295e53a43571de420e7b1", size = 567888, upload-time = "2026-10-05T17:42:59.048Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1f/7676f46aa24554a45686853c61552d02d67ade2b4c51adfe8b2ec4fdecd2/aiohttp-3.14.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f28a3c4fca436b2e594090e7cd22558f5e93a30ca18516c436de982da6fc25a", size = 2054356, upload-time = "2026-10-05T17:43:01.781Z" }, + { url = "https://files.pythonhosted.org/packages/44/79/b9ef7d7442061e0a3125990d6021230b30361a972f7b8ebfb011042877ce/aiohttp-3.14.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e099aae21246992a1d84303ff262262d054c474e46cace33b0d5a69810c71877", size = 1937678, upload-time = "2026-10-05T17:43:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/5c/98/5927a31540c8e6d0542effead5bd5c56e749a9d99d84e902fb80ae906ef8/aiohttp-3.14.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fafb521891e646d9cf5da89f01c75e7159d08be7254a024149630a698be28251", size = 2026705, upload-time = "2026-10-05T17:43:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/62/bd/1be001ed97dcfa57a292188c38979fb78be795b960b50f02660587bffa06/aiohttp-3.14.4-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d385db2cd154bce0b3dd451cf2a52bec91ebb7be2c3a5d06b14b4391631d807", size = 2147075, upload-time = "2026-10-05T17:43:10.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f7/d59628ccedd7c86db4c1f904467d1c80fed6cc10a1831ed5d75ff12e5a71/aiohttp-3.14.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ae8a244889d8a53549851bf595b9f382f64acca57e8762da1ecb26ba786828f7", size = 2005016, upload-time = "2026-10-05T17:43:12.848Z" }, + { url = "https://files.pythonhosted.org/packages/3c/dc/472db3ab1daafa12a61d7f83314f85f502b99c143c78d66554a5e24361fd/aiohttp-3.14.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:681dde68ff8d8d5e7d5abcad4feb45bfb457a218310c919825e21fc36cac3d0b", size = 1796363, upload-time = "2026-10-05T17:43:15.562Z" }, + { url = "https://files.pythonhosted.org/packages/08/61/6f9834b131b9a42e30d68c469c196033d3cae2d8fe340d4668f362c4fd1f/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b91a6441fcaed88ca7bca67726b189332df3ceb6ac0dfc98dcb9654bb723288c", size = 1974240, upload-time = "2026-10-05T17:43:18.884Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/b8eb2a276685ef1da7f7bc15348404b8b9ee12b8f32f2cd8895385cd1589/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:f15dbbac49bc15eaff95c0b8166525c4050996af578c7be141e145f40ee2cf24", size = 1973387, upload-time = "2026-10-05T17:43:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/5b/32/ad559b2d6817e85f7cb294d8641e975e64b526f4da98ffe941c9af67a047/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7abae043e87692d1c2adda1fab501bb0612d28c4a23eb082005c1e684f792dac", size = 1968766, upload-time = "2026-10-05T17:43:24.544Z" }, + { url = "https://files.pythonhosted.org/packages/60/67/4a16e398140bdabb363428b9f439af3f77706a6df8bea6e626bbde53c2ab/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:21f4624fb1051fc1aa10d57a636a80e829f7d0417462d6f1ce380b08fe1a904c", size = 1788193, upload-time = "2026-10-05T17:43:27.467Z" }, + { url = "https://files.pythonhosted.org/packages/a9/38/17b326da7f52e530a675d789ade3e727a1b3db9959722f6049b9c392321a/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:2e8dc3a0fdaf9d12b954d3d06cc4c355d91b17fb6c671715b593624ca4c379f8", size = 1999645, upload-time = "2026-10-05T17:43:30.32Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/91b87961250010e05eb3adabaf0d98e4229ee7543147c265e834922e1b0b/aiohttp-3.14.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:1410b6f6e3d52ea7c02c950496522ce6e85d5543bf154bc80a6141e505251cfa", size = 1970998, upload-time = "2026-10-05T17:43:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/72/66/9bcf2c2db7b75a3b51c11470ceb67941d028727d674276ff5d5120adc87e/aiohttp-3.14.4-cp315-cp315t-win32.whl", hash = "sha256:a65189a89f3e621f7c27a968b5131bbca29126e2b8517dc72b205747a39d4c96", size = 504036, upload-time = "2026-10-05T17:43:36.212Z" }, + { url = "https://files.pythonhosted.org/packages/e2/20/349db4af12dbc16070d32028d30c2067123b4520f3dcb2d9013524efeb4f/aiohttp-3.14.4-cp315-cp315t-win_amd64.whl", hash = "sha256:2b2c95f5f769eec92b552969db1f79ea0282058ce5131ed0f2fa540b4af3f14e", size = 531284, upload-time = "2026-10-05T17:43:39.362Z" }, + { url = "https://files.pythonhosted.org/packages/26/21/544c711bc5fad611278ebd153bdcab1bffce8b8581f8ec9096b275948a3c/aiohttp-3.14.4-cp315-cp315t-win_arm64.whl", hash = "sha256:54209fff79346ee1ef0d5cbf92fa80a5bb37396406bb4d932e5107f9c29b2d3f", size = 510623, upload-time = "2026-10-05T17:43:42.15Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/5e1f8446545be98e9416af59c396b1ed1f9f3294afb0a40ee3a709889273/aiohttp-3.14.4-py3-none-any.whl", hash = "sha256:5c6758ba62aea282c537179cfc8474a90f2b5f7b089cc5ff66d8920d86a9bfdd", size = 279487, upload-time = "2026-10-05T17:43:44.905Z" }, ] [[package]] @@ -1969,7 +2011,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.70.2" +version = "7.73.0" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -3125,142 +3167,152 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/75/16/e8be8e2fb175bbf41a0680381a319f1199fae256588241a2ac8677eafb49/yarl-1.25.1.tar.gz", hash = "sha256:03dd38de09bc213e9a8b29761eec33ee1d5318dac0e49d8af36e4d27830e23a7", size = 246245, upload-time = "2026-09-15T19:35:02.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/92/55fa9ee84cb8ec9930a910b5753936a926f918d8cc8965bdac571479c095/yarl-1.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:142c06c4d6a35ee3ec5da08499805e879cb3ca7c1fbfbecb0140fe72403818d6", size = 144695, upload-time = "2026-09-15T19:29:53.114Z" }, + { url = "https://files.pythonhosted.org/packages/16/b4/9edc8e605b16b2eb5bd0c2ccc73e2b15aab583862460767fb43f91f11839/yarl-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24ce942011a61953e7d313438038f4d32ff21387b775f58a957f7a07dd55ef95", size = 104332, upload-time = "2026-09-15T19:29:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/ae/de/4204e6646e278b1cd4a9cf73ebe8b7cfcf16693f1249b324eb273d67602a/yarl-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e23c82b63cd7652fc24d33ed6cc17099d607aa3b4fc4ddc75e95062f3d82df4", size = 104449, upload-time = "2026-09-15T19:29:57.239Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fc/21d74789198ad68a23a209ab0d73fe5a52d39ebbd9945041e72827acdd77/yarl-1.25.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ee202350cf57abf0e9502a41601841019c25d3db7ff52d980aaf31446254059", size = 116828, upload-time = "2026-09-15T19:29:59.031Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/90891ddb61848c067ebd1fb505ab5902a6e7d4707c2f3823f67ff37883d3/yarl-1.25.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5df89f769cc8ff94c3d7e7603386fba309d25ce5240132d26c15baa8d0e96c4c", size = 107150, upload-time = "2026-09-15T19:30:00.868Z" }, + { url = "https://files.pythonhosted.org/packages/a1/15/f3d18743d3688b5f01aa83034b6c00665692ab20e1d0c89a29000d4979ea/yarl-1.25.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83e9f4a25085bd4b7214701a0794ff1f50fc633ffb8bdfebf07abdd81c2db126", size = 124704, upload-time = "2026-09-15T19:30:03.128Z" }, + { url = "https://files.pythonhosted.org/packages/99/37/718789d8004775d6a2db86b2afc72b1d156e0590b88a1b8634ddd4bdb8ee/yarl-1.25.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e636b64d24fd9c38053c5e389a1174c66361fa49dcfd220f4dd35b4abde7cb89", size = 129246, upload-time = "2026-09-15T19:30:05.014Z" }, + { url = "https://files.pythonhosted.org/packages/28/b9/7818ac6dec7fbcd16be2d19495807c01e2c38834e57d41c63356a75e786b/yarl-1.25.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e5637ca8d0bd7fb72648a6c7934af4baaccb697657f7438c9d264fc2abb8b0b1", size = 118071, upload-time = "2026-09-15T19:30:06.977Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e3/8d098cafb30a64df7283b5a5dd0d32d22a71b18a1b9ec071d0776ffe5c2a/yarl-1.25.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:683e362b8ba453080f7489c66f4ea794e751c35b72e7eab3575ef784c2fbc7fb", size = 116180, upload-time = "2026-09-15T19:30:08.836Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/fbe9432478d87e00eef80242e15179639df162cb3d5d8d978fc56dcb6c51/yarl-1.25.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:df23df54b5114a17c2d0ef192433e2e5a9f0c5178c32375e90b7cfc965f349d0", size = 116578, upload-time = "2026-09-15T19:30:10.782Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/b3dfd03732236b86b0bcf06a72a37de412ff6f82e719a947c3c651d4dece/yarl-1.25.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f53dcd26694f148f738edc052b5a69234833e739f10f4c3287bdfd8ec0f7b326", size = 108886, upload-time = "2026-09-15T19:30:12.951Z" }, + { url = "https://files.pythonhosted.org/packages/83/e1/94dacb650d4963d5f844bc3df7ba70288cb7b68ed5a4d070da71acb19b14/yarl-1.25.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8075fe90bc08e40b8b8a1874fab42ee4c7b56af05c5886e9cc841397f916908", size = 124098, upload-time = "2026-09-15T19:30:14.963Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3f/c93f76a218258c7bfc60dd27fd56e9102bdbc625517f4a6ee673295fe4e4/yarl-1.25.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:a8c2b841478068440d8b733005d13a5ef535b9928cbc05f17182d410f32ba449", size = 115768, upload-time = "2026-09-15T19:30:16.736Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/4d93f13c3b05cda3c962805dec28cbc255c50239b3457808abc5633a00c2/yarl-1.25.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ca32926d7d77bcc8838425c4c95e040a3ace1cb7dfdae599013458dcda2607ca", size = 122461, upload-time = "2026-09-15T19:30:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8e/e2ba83b3a9bfc1d3b882ad35fa8abc04a7af4d9356f2e329a23d0c8d889d/yarl-1.25.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:192a866877a49993949ef1975864ad8728bea28ee810f6abe1a0729c2b500426", size = 118295, upload-time = "2026-09-15T19:30:21.07Z" }, + { url = "https://files.pythonhosted.org/packages/42/67/cb5ea1baa0c0ac60bda44ce59f601133154af2a2e67722d3517f8793855d/yarl-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:3f4d48a6112712973e676bd792121fee470e432d749177162d9949d5c9460a1b", size = 102929, upload-time = "2026-09-15T19:30:23.122Z" }, + { url = "https://files.pythonhosted.org/packages/2f/85/9a1e98de10fc0e738d517efd2a9984c3e7db6cf35fa72b2b373988a9e9b7/yarl-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:48796ea00a303961507dc6c8437c4b325a6fc3f95f7c36c71b91ea9a8150963c", size = 98854, upload-time = "2026-09-15T19:30:25.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/b3/2cea721d495ca57f8f414aa4867ee263f486b274e07463158cf52f02ba7f/yarl-1.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9d693bf4bf534e9ba3ae2780cfd577f5135629f7b5ac653490859d0b77864865", size = 143794, upload-time = "2026-09-15T19:30:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/55/e6/cd145cff8e5cf60b8b3c41fbecfa2a45028a8dec3fbc52bec03595ff3d3b/yarl-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ab2054c5531af2a9ba7b69b8ec91e4f884420e83a8c5e579b013084cb57e5e5d", size = 103993, upload-time = "2026-09-15T19:30:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/ce/7c/fbb40fe2d53747c40aa36a9e2bd2178a202f942bda0b670f3306d4aefbce/yarl-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:564fdc7085d2245ab84f88882fdb1d6ac0723124bff6ded35bfb1c00f812630d", size = 104010, upload-time = "2026-09-15T19:30:31.069Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0b/5a516f70641092283f57cf3670bdb75e7327bcc0dcb5038697e4dfbfd569/yarl-1.25.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acae6b45d1ace09b6ba3876da43b88366ef368f73b988c7f57e14231753d4420", size = 116444, upload-time = "2026-09-15T19:30:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/d1a627f827b0a404ae0f5647cab0534959081cde13b0756a783469fb3b5e/yarl-1.25.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fb2a01ba8cd9c5d2c5dc1ec35e0fc951d04b4f037541d4ac090c993ce58b3d7", size = 107565, upload-time = "2026-09-15T19:30:35.188Z" }, + { url = "https://files.pythonhosted.org/packages/aa/cf/c8e0aaec886840a6c4480fe44eaec7cd4319f79a563b79321473be79c56f/yarl-1.25.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e92b6bcc741b86d67606c40d3cb9c7cc8e6c737f81e31f4a94efc204456c92e3", size = 125006, upload-time = "2026-09-15T19:30:37.1Z" }, + { url = "https://files.pythonhosted.org/packages/50/26/0cce366d54a93cdc8342965dc7663385e4db161625cc1e8b18e786753d24/yarl-1.25.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72c34ac7ad4314c19362d5ce27626dcc8429bd30bbf8c179f4234078851f9492", size = 128717, upload-time = "2026-09-15T19:30:38.904Z" }, + { url = "https://files.pythonhosted.org/packages/95/0c/a71501bbc1a674ff72c4d6c2b75f4d9a5af819f5244c3a7558080a8802c5/yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5add7b4ca7afeea91d52e4d4e4db3b1fe9885b71f07054560d8c4296b7441a2", size = 117728, upload-time = "2026-09-15T19:30:40.809Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6f/c3267ca01defeed9ed9c4ff9b17bd54915432c405945233265b707475d1c/yarl-1.25.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:def538065f9e4d4cf1ae164bd59aba00dfa84f03923e0de4c3788f252d6bcd17", size = 116224, upload-time = "2026-09-15T19:30:42.818Z" }, + { url = "https://files.pythonhosted.org/packages/8f/69/fad57ee52d648431718ee0f1f68966a99c1352c3924688ffbdcc9d3fe51a/yarl-1.25.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a191bfdb30a79b98e5d175d75285f9fcb78bf0e46ba5efda042e1c72071a0de", size = 116299, upload-time = "2026-09-15T19:30:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d4/6a8c1e29f33338687ca278cba0a8fbf6525a322c2c02a9a500ccbe041152/yarl-1.25.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:71f42c5b9a948c113bbdebfa544598321431d064ff959d32e99b1feb61d68345", size = 108625, upload-time = "2026-09-15T19:30:46.874Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d2/3a35ae791c9cb6522c106923ff25c3230d999091e5e65511bca23bbd9914/yarl-1.25.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:72849d892954be4d09e569b8b831ac39ce58417fedc767d4308a0fe542018a40", size = 124515, upload-time = "2026-09-15T19:30:49.082Z" }, + { url = "https://files.pythonhosted.org/packages/be/fd/2b022109a6b4af0f7dc371cf7500af380b0d4f034010243e1b0ce218dc93/yarl-1.25.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:efb01a106f971cb3752856bca2318bbdf7f01bd8823779c461586cbe5ffd5258", size = 115711, upload-time = "2026-09-15T19:30:51.208Z" }, + { url = "https://files.pythonhosted.org/packages/18/59/f7586271136c3ddb0126bbfe661844699369b76b555fe38c4efe86870b2e/yarl-1.25.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a1daf47cd95a7c3a63456336bc5aaa8c86dd3a47d07ed3d0e76132ae4666a5a1", size = 122751, upload-time = "2026-09-15T19:30:53.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0b/07f7a2d881f7e16c385b47fc1753382600847cad305dcc7fa0c25828acf8/yarl-1.25.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9489e6abf47ba37f332075a91444c7cfedb03e6ce99fbb2f116bfe1ce810da3b", size = 117983, upload-time = "2026-09-15T19:30:55.277Z" }, + { url = "https://files.pythonhosted.org/packages/aa/9d/8cdceec66a9b940700cb45931741403f045b162afd79bcb93c41cadd0972/yarl-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7306dee25b8a0e737363f347362b875094b4dc4e367311470656ae420fdbf8e", size = 102894, upload-time = "2026-09-15T19:30:57.606Z" }, + { url = "https://files.pythonhosted.org/packages/17/f1/7ec357db1d3ad2863542d71e8fe64a126bbec17b134cd7d30951196809a5/yarl-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:abb1384477f5901d436b5d2e5465954de46ea6098f59163d243660b5c4461d35", size = 98609, upload-time = "2026-09-15T19:30:59.705Z" }, + { url = "https://files.pythonhosted.org/packages/75/b3/cd32ac66ae622b854c2df0ac52106dda220d361b65a64fde7d5b3684aa3f/yarl-1.25.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:94d7aa6debf92a1dd14cb5280b083a764169a13cfb23a452111160274ed989f4", size = 144798, upload-time = "2026-09-15T19:31:01.821Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/a2c52a8007c2051ba74662afb112ecf3d00346af4c25e33df9d80fd14fb8/yarl-1.25.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:83d4a37e4b95da4d8bda930d6d35b75b4cdadbacbb4980cae290ea3100b5d51d", size = 104583, upload-time = "2026-09-15T19:31:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/be/dd/ee38aec8e09fdf957e50d4085453fbe202f56c6c3b4cf07b81cdb4f09ee9/yarl-1.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e029648f9c951db30e98a7d7ec90835db88ec4b32820efe2a9bdc2287e032eb6", size = 104325, upload-time = "2026-09-15T19:31:06.338Z" }, + { url = "https://files.pythonhosted.org/packages/1e/b3/058dbfb1857b484c9cf9cc135659f50b85ce66e03c99e44dc2f7b6161f55/yarl-1.25.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d781294bb815ecb5ea57ff6bbf8038e0a31a95fdf3e1788f66e0dc100d64b58", size = 115358, upload-time = "2026-09-15T19:31:08.593Z" }, + { url = "https://files.pythonhosted.org/packages/db/39/29693446cf0cf6b15a0e2f75a5d40f93c56819b05b0622196f45e95b5cc0/yarl-1.25.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e12c538e00e7c1b286a07061046b90e8124e6a9793efae2c70db6a4aad07faad", size = 107658, upload-time = "2026-09-15T19:31:10.802Z" }, + { url = "https://files.pythonhosted.org/packages/86/b3/3c4dd7e1af43b931fba95e0a722737f2ea94a6d199c802585282831d7abd/yarl-1.25.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e4de3ac4adbad3d0bc7c6f4360a7dbff5de2f15e3b723be3198074e17fd9c40", size = 122660, upload-time = "2026-09-15T19:31:12.84Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b5/1b60dbc3cfc9c5712b15148c206748f2bc93953ffdbe25ea75b63dfc89c9/yarl-1.25.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:419f392a1da624877975709e3864dfe833af6cc7671b39318086d456e288380c", size = 126506, upload-time = "2026-09-15T19:31:15.088Z" }, + { url = "https://files.pythonhosted.org/packages/bc/7b/ca212cbe170ac8b96e45317ecbcf9c3c3ecf0cdec98d5b088a9c4088929b/yarl-1.25.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6f117789d22dce188e5754e8bc65b7e6ebf8cb73963b9fa761f672a5883769d", size = 117050, upload-time = "2026-09-15T19:31:17.241Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c3/72b4938cdbe619ad71ac156182faef4908846b84dc3ca4dbb4c4e6f84014/yarl-1.25.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80e47012e730da131c9f059c80936783f9659aae22dc31c03c0595590d11ed54", size = 114174, upload-time = "2026-09-15T19:31:19.294Z" }, + { url = "https://files.pythonhosted.org/packages/e8/43/268717870f9ba0cc9701a95181587f6dc8c5f387aab4aeecc83158f38a79/yarl-1.25.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e80f557716fd765439577131e526b8942ffc2c07bdbc5e39fa62f660ba1e963f", size = 114944, upload-time = "2026-09-15T19:31:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/da/84/baa5bf504d51fe062c4bcaf62936da97fffb43285978d0b39984824231fd/yarl-1.25.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f61964f235a43738bfac50da46fc4254943a7eea3051aeb0b6fc7c992c29fadc", size = 108263, upload-time = "2026-09-15T19:31:23.388Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/779a2ed9e0152a601a27039bed9aead3f0b79797a67e2c44bfa444622dd8/yarl-1.25.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e546fe1d4a93ebc2910f0d768baff19faa09843ab3f2036a67ed6e69fae4419d", size = 122184, upload-time = "2026-09-15T19:31:25.343Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1f/118e9e5b8f07694d63fd3222e801d7782270003f1a222aa798df3f8d5933/yarl-1.25.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cce0727fd5ac04d372fa9bbfde9febc2bcf209aadfcf0468e45dec72719895d1", size = 114001, upload-time = "2026-09-15T19:31:27.465Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/a4cf1cf372313734b17996d4007f9f73596e7a178b9485802e5494ecf484/yarl-1.25.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af4ea5b37403ef4e30f3927eaed540db942bde01d8d3ff083527c0704d1c9c68", size = 120565, upload-time = "2026-09-15T19:31:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/05/79/ad94f93ca731bc9e44d321833ab96b82a4f9f5f63cf773f81a4aeea5ecc1/yarl-1.25.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:68782fdb4027b8d1eee25ec35e9a6db05e863b899eb0310b3a33b6c3fef55707", size = 117060, upload-time = "2026-09-15T19:31:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/bb/cc/51a7b4abf4ac593b8e7eb3794b28e5a35ae26eed8bc04787628d215af82f/yarl-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:7d575b54cb3863ef9bc290ea4b009999d55dc237326131e4853cf33e888fee03", size = 102593, upload-time = "2026-09-15T19:31:33.329Z" }, + { url = "https://files.pythonhosted.org/packages/9d/21/0941a6b93a58b59a1ec75e5333bf06929b671309c43c0cd201c172d9c39f/yarl-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:bc3ac7bf569f6b64dad04dd7808c7872dae8a97df657856eac05e9b7e3614a85", size = 97697, upload-time = "2026-09-15T19:31:35.855Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/2f3129bbcc9a5c8ba12cc2b29d8060a3bab9c8043c456cfd4b5ca3188890/yarl-1.25.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:25868beca8b6765f8f7d0e11fe6dd7c66dd4b0793b9500286d20cc92352126a5", size = 143623, upload-time = "2026-09-15T19:31:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f1bc3390fdca352826676b531d0712736f156919090206700421d46b2c37/yarl-1.25.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10b2fd95332f0d716d5eee3c9fb2ce8eada19082de7fee83d32e37992fd75c26", size = 104011, upload-time = "2026-09-15T19:31:40.25Z" }, + { url = "https://files.pythonhosted.org/packages/a8/aa/50acc5c3e5da04172ae3c281c75405af4d2ca911e16120ab0563f4dffb66/yarl-1.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f12afda4eea8c8994a76d4df1875c765194f5fbe8a9d197929ea303caee29ec", size = 103677, upload-time = "2026-09-15T19:31:42.46Z" }, + { url = "https://files.pythonhosted.org/packages/30/d2/7d1e0ab9f8390e1fbcede5a6dbf70d23c96ad09b8c5567f3a514d1ddb0e2/yarl-1.25.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14b79a30a93a3ce2e8832603fd0ab780ada281b0ba5110b519a634f2d7d7d1fc", size = 115392, upload-time = "2026-09-15T19:31:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/71/e1/5ba1e3a2a22139213655e760919038e8ed7e2d4a99826d0bbddb3beb96e5/yarl-1.25.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4bd6340d20ae2c7ca719b87b426e808e90743b676d05d4c26c4fb5ca71f41184", size = 107493, upload-time = "2026-09-15T19:31:46.273Z" }, + { url = "https://files.pythonhosted.org/packages/f5/53/780653d5e0f73831f467cf13548912e5eec97f21dc49fc8daf21da027df4/yarl-1.25.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:126a2533570c554719ca40a1288fdee1700b6bc82e7131aa69fa85252d92e651", size = 122537, upload-time = "2026-09-15T19:31:48.654Z" }, + { url = "https://files.pythonhosted.org/packages/03/92/d54fa70236c6036271c9c9c09fd978df5cbe3ef49ef6c46e9b833476d215/yarl-1.25.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a3faadac7d812ddac258feb57b9846b60c1b437c4f4b9ad42595c6f6fe4390df", size = 126170, upload-time = "2026-09-15T19:31:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/0e/b7/a82a49bf88340b837ef6972b508a1604ae377b9e6904b46b10cf5f1cf925/yarl-1.25.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be80550d9bfe83d9b62398a37081a90434e6df2d978ec345c3d2820de6beddab", size = 117012, upload-time = "2026-09-15T19:31:53.189Z" }, + { url = "https://files.pythonhosted.org/packages/ef/78/5d684b411e3f3602464ee9b538db48205038f8605872985f61efb809ced0/yarl-1.25.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e07595c7d6f4db270ceede356a1bd1c07a34f1c26f958d1ed0cd7b48e0d2bba3", size = 114950, upload-time = "2026-09-15T19:31:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/2f/11/51d82b852c64f7fad0fc7a7ff3031517204887e874c722bbca839c0b23ac/yarl-1.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eb96ed1ae6c7d072d60840c0434aef07a2df611812810807fbc54263a6053e9a", size = 115428, upload-time = "2026-09-15T19:31:57.966Z" }, + { url = "https://files.pythonhosted.org/packages/e4/49/9d1978049bf646b9ea918313926453c6901b71c92f097467777d47d36a88/yarl-1.25.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3feb99222553a8cbedfa52c2f59dd84c3f50d5b582c728d522caf8d72769a54b", size = 108428, upload-time = "2026-09-15T19:32:00.048Z" }, + { url = "https://files.pythonhosted.org/packages/43/35/7b8f1ebb45d7ec3dda7d1909bf44f458de41ef91e2937f107733582a5166/yarl-1.25.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a2ed0ba415ccdf08f14bf544cb78346d0f76086707ffee24921a2c84dbf1305a", size = 121961, upload-time = "2026-09-15T19:32:02.436Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/d8b689ab7ca26edeb85f6ff28812aac7a25376eefc1780e303a7bfbaceff/yarl-1.25.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2b49375d22299b0a834c2bca72f39aaecc270d96fb24c30424899676f487b22a", size = 114961, upload-time = "2026-09-15T19:32:04.456Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/1a1798ea4dc6b7ee3260010a27907ebc697c95dae99817d817ed446d24aa/yarl-1.25.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ef74070ac553c59eb4f04258722066d6c6135b7baa03b2e9f2da65c096e96d98", size = 120036, upload-time = "2026-09-15T19:32:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/91/8d/b1b35ed7903da6669b1d367cb2c09436acd4ff508029b4f39a0c0c2058fc/yarl-1.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0a66db89ea473abeac4b70523cafd94db3772380e565f9d28af7a179b7af71fa", size = 117276, upload-time = "2026-09-15T19:32:09.401Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8f/4db01cef62caff0d7a4593ed694fb8a41a27a11158cab80d290221f13e57/yarl-1.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:1f51020b2eb8a003c84925638ec63c21a750a4bddd3a22ec8eac6a742dadf1b9", size = 101945, upload-time = "2026-09-15T19:32:11.545Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5e/3ce00497c5c0babb74d4130c10c3828ccd215b4819d12020c42429f991ac/yarl-1.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:b10dd0557ba422715b5206b3743192135a6022acca8baec51aa127d0a75db8fe", size = 97270, upload-time = "2026-09-15T19:32:14.127Z" }, + { url = "https://files.pythonhosted.org/packages/80/cf/54023edfab7aa773b860503db0c56e962ccab0922803ee97988c176ea090/yarl-1.25.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a9ca696eb02e5c02a8afd872ada510eba9b7fe6e68b9572c2e9a9b1941e31e2e", size = 143975, upload-time = "2026-09-15T19:32:16.416Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a8/e6c1be0e6761d0f2d10bbf33a3e1e02b99dc83874d92945d7b461a72481e/yarl-1.25.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a5877f2255aab518ebe528289037699201d5dc5f045f2396cb30aa02db22f57f", size = 104018, upload-time = "2026-09-15T19:32:18.364Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bb/dda344765ffd3430afe1a1c66c866a57fae67786537d4f14607df6505ac1/yarl-1.25.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7a5c3115595995779ee21f2567035793911c3802a43c74f3fbb0314929ec67ac", size = 104156, upload-time = "2026-09-15T19:32:20.459Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/ed1538bcd06009fe990d6d283dd7667f639e62a81e35c6d8c6ef6c08fb3c/yarl-1.25.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77e5099b99b37f3cf79c246998ca9f7313a78054cd1809ec46bc1afad47e1c4c", size = 116025, upload-time = "2026-09-15T19:32:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/a2/af/2185daf56b99830d3356ecfada46faaa49945de6626e842b7728088d4980/yarl-1.25.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6efaf45df6a849cef613a03a94c845647456662f85438c886bb67a9c027c8c2c", size = 106985, upload-time = "2026-09-15T19:32:24.749Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/bc1ae564fb4b04a30b6a8f250e787772581c57e4c3d5cf07ac3359de3103/yarl-1.25.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5f90e44653c4e0f78501ed9bb7d3fce835a8d62b7c6ed0cb16557534087e743", size = 123030, upload-time = "2026-09-15T19:32:27.084Z" }, + { url = "https://files.pythonhosted.org/packages/6a/3e/e2afcde10d74e53b3fa889960991efb3019beda2b1682a01de720a302056/yarl-1.25.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:632da579b2d879f6bad20f2cfa35ded1efe2f4f77f8abb26a6234a5b236acd2f", size = 126765, upload-time = "2026-09-15T19:32:29.332Z" }, + { url = "https://files.pythonhosted.org/packages/a2/be/415b00c0fe5a0615b062a456b26623d7ec91c2bee20faea1a14045aa0469/yarl-1.25.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30eec96e8a91bd588ce897c9543f6d5d8d34b28fbcba28a4dedf20ebeae9fe57", size = 117199, upload-time = "2026-09-15T19:32:31.49Z" }, + { url = "https://files.pythonhosted.org/packages/97/27/3d8c63ddd3e8bcfd033748ab93876678ce59bacd66e4cb1ed851c9c5b37e/yarl-1.25.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:12b6bc4906e11f5e1a1cdcb12296e7afbd366c783cc8073403cd2fb74334e453", size = 115187, upload-time = "2026-09-15T19:32:34.137Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/7a81d0be1a502a26a0d4326c6f2ecb736c824f570ea1c6529f2b0b227b50/yarl-1.25.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9d6ed3d17bccce4c05343e1ca8da13bc5c02c812a4e7282ddd05e8769322d3fc", size = 116085, upload-time = "2026-09-15T19:32:36.438Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/39fff459916aa0fab42215dc47b759586fd80f94aa56dfc4a7c15ba6e0dc/yarl-1.25.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:f38a70074041d3b7e138e452799f5174198bae5bd5ab2000917badf403908c5f", size = 107996, upload-time = "2026-09-15T19:32:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/c0/39/80b9a55a3335590451d9ecf3eb593a8c635351f4c905ef056d7e8a8fd9e7/yarl-1.25.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca89e4e21854ed27ec753297dde84b16c9f8e53b14a4866fb44457d643c19f8", size = 122549, upload-time = "2026-09-15T19:32:41.151Z" }, + { url = "https://files.pythonhosted.org/packages/42/7d/a179c6757818bb59372a4adafd09f7f26a3b4a0f04c3ae404b544c0b0c82/yarl-1.25.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1ab7618921a93767387a4b83776f751588f5b5ae9bb5bc96620e2e2e00bca868", size = 115107, upload-time = "2026-09-15T19:32:43.072Z" }, + { url = "https://files.pythonhosted.org/packages/32/2b/a773ac867e4ab53a98ed98e5cefe3bae31e6f550252ca9d1de266f1a40c5/yarl-1.25.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:0ae12ff2b805fa02c4dab838005caef735e39986322698c48588d3beacb65c62", size = 120666, upload-time = "2026-09-15T19:32:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/bc/41/52be6505e85b0f76b4f85b01b5de7e06a0512201abc2c95e14e099549174/yarl-1.25.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90c30ed53546da833c700115c0064c22120d1b1560f474699fd31f22dd668233", size = 117505, upload-time = "2026-09-15T19:32:47.177Z" }, + { url = "https://files.pythonhosted.org/packages/f5/01/349c0386caedbbe488d519f252df54efac8a1459282d466c474bdd84a620/yarl-1.25.1-cp314-cp314-win_amd64.whl", hash = "sha256:acfa7e22aa6c6e7a5996a41d275bfa01efa7ea56ab890590280e9063e2cf5c1b", size = 103446, upload-time = "2026-09-15T19:32:49.615Z" }, + { url = "https://files.pythonhosted.org/packages/5c/f0/8ec63180f77912f0dc4e5a42760cb8c08d20da1d5ace3578a01b84d1f3d8/yarl-1.25.1-cp314-cp314-win_arm64.whl", hash = "sha256:8e7d98cdbb6d71e726f7d525952867096053d1f290dd4e3c50d7d313a136f414", size = 99159, upload-time = "2026-09-15T19:32:51.686Z" }, + { url = "https://files.pythonhosted.org/packages/47/7d/92d2220d6886b70ab1ed8579533ac2af2dfac716d5d929001daff7986df9/yarl-1.25.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d21f0fa80a02d05299207eeaafef345d812ace96d5306e4ef265e1d419a615fa", size = 150071, upload-time = "2026-09-15T19:32:53.911Z" }, + { url = "https://files.pythonhosted.org/packages/64/fc/b245e448124bcda9340df38e3553fa222b50260fca027a84095e9bd8642d/yarl-1.25.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17c9877a89fb6e2bca6f9087eb24cd7fb434653946ef5075e470d23d49b52287", size = 106780, upload-time = "2026-09-15T19:32:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/51/e2/9a6ce2e334ebf218a30335ae76fb1696459430d42f733b8cb0d7d65b84d3/yarl-1.25.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29273edf1530e397bd07cb784db1fbe0d2590b77569f2e24679a9c0a2d763b94", size = 107361, upload-time = "2026-09-15T19:32:58.827Z" }, + { url = "https://files.pythonhosted.org/packages/ed/70/66e8c76b569b450d16e190f15071c916c3df70b0e33927e415ac497cf0c2/yarl-1.25.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7abffdf37af1cec6a2ad69b827aa84320db5894791bc8ed932dc93fb274b7e9", size = 114396, upload-time = "2026-09-15T19:33:02.24Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/0d82838a05c57fdc05bc8b66e8c92dcc0df15e27463a5f163142d521c682/yarl-1.25.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2239a02249d9326655419e0168a28ca9008938eaab31dc29fc875c217927a6c0", size = 104882, upload-time = "2026-09-15T19:33:04.494Z" }, + { url = "https://files.pythonhosted.org/packages/86/d4/ea08615c4edaa6049a13a2f1128944d068d1893abda7d708d4d7ea01599a/yarl-1.25.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:664ec6a520b74a1df2810666eb67695fcb77fa663e6ea0a25aaf2e529cb24dfa", size = 119485, upload-time = "2026-09-15T19:33:06.583Z" }, + { url = "https://files.pythonhosted.org/packages/1a/82/0898bdce9b1ae403b308b9c733d0d24af4a3464270c2c081f457b16c3e0d/yarl-1.25.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4f1c91f5a5980a937ff8e238e98e6897e1ad74a4b1e2c0d68c73b5ffbb3f5c0b", size = 122490, upload-time = "2026-09-15T19:33:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/d1/38/97d79b81c342b78246cfedb74809e68841f3198d21653e10d3232bd9c622/yarl-1.25.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c88edaec8c349ad4c5ad4c486a3defcc4b80ceb2f074436ffa0a87caf5e76a6", size = 115336, upload-time = "2026-09-15T19:33:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/8e/9d/2577896554cd310dc470adb6da0b7dd0b435cb63e2565204a7ac240e504c/yarl-1.25.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:35dcbea443fafb3eece757ad4e514560ddeb6c34cfae1582c620d7b293d7feee", size = 111825, upload-time = "2026-09-15T19:33:13.204Z" }, + { url = "https://files.pythonhosted.org/packages/29/6b/7ac49d8ba84a5c4bd73415a4c949d22c749cb3762579b3d50e48019a78aa/yarl-1.25.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:882569ff613758cac762a457a5d72d6e211b28d4bcfea89d1d71ea942b02eac0", size = 114655, upload-time = "2026-09-15T19:33:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/e5/18/e5942a16723f5b72f9b1297fd5a85a54f6300cd15c0dcb5005b90cd89156/yarl-1.25.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d0f1489233a254bb3643d2f05de7d59019254d81daeca6b9162fe9edef57e0c7", size = 106395, upload-time = "2026-09-15T19:33:17.599Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2d/549fa46240781513ebc47ae7eb418df428a163a2a3d644cc9cbb3ecb7846/yarl-1.25.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f41753a76f4f63927d03a0d8ba8f5ce0f2083bec29a8cfaccc55371b1564b96b", size = 119277, upload-time = "2026-09-15T19:33:19.973Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/4763f78dcdc0b3b9fb3842b04afe72b9320857c6a69300c62a0eab03d119/yarl-1.25.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8fb0eb4955adf0579001581f2f71a126e8781ba61bcd120f127b0401163c6c2d", size = 112504, upload-time = "2026-09-15T19:33:22.464Z" }, + { url = "https://files.pythonhosted.org/packages/ae/b4/974e3edfe0d188393ce1cb9de400111c63fe61f4eb3b772a500d84c970d1/yarl-1.25.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a1e32763e641a1566507d90a8d3b19bfc3cc04a9d4e5ae3e32189874ed4b58a3", size = 116243, upload-time = "2026-09-15T19:33:24.788Z" }, + { url = "https://files.pythonhosted.org/packages/b0/aa/157b940428da80c104ca09666a740e51c94963df65d5b112e06b52e4d7a8/yarl-1.25.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65b5b2066651b7432d389e9799d979c703bcc6ef44266bb8153ef54e91e4aab3", size = 115822, upload-time = "2026-09-15T19:33:26.886Z" }, + { url = "https://files.pythonhosted.org/packages/7e/af/19fbdce41412e1b96825544cc52cd7029d3724655d0988237972f078bd29/yarl-1.25.1-cp314-cp314t-win_amd64.whl", hash = "sha256:734f6e5400352ac4254456003d462866c684703570929cff7a7bde015d0cb371", size = 107386, upload-time = "2026-09-15T19:33:29.009Z" }, + { url = "https://files.pythonhosted.org/packages/2a/99/f6431c8968e89be608d74b28ae2d024521b2953f27dd44e0dece5e04f67a/yarl-1.25.1-cp314-cp314t-win_arm64.whl", hash = "sha256:287e99ff5aa4dc1c7630bfc683ded6f106d756c99dec432a2d7f197a784f51c6", size = 102094, upload-time = "2026-09-15T19:33:31.151Z" }, + { url = "https://files.pythonhosted.org/packages/c7/3b/4f51eab40c2eabea6c3d5b121dff4b8988dc35087732ffede12d2be8b8dd/yarl-1.25.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9b1bdaae98bc016825dd3c9d8ee1832f829b3341f9cc6ebd1a1b0a7fef7367cc", size = 143875, upload-time = "2026-09-15T19:33:33.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/05/bbd58fc063f5f299a883f810760b265ca26c8167c91cb9a494d0fe2387e1/yarl-1.25.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:e7011b8fb8c4054bf0c12e5edc6cd83778b0028e99ce59b18586ed036f92cfdc", size = 104028, upload-time = "2026-09-15T19:33:36.22Z" }, + { url = "https://files.pythonhosted.org/packages/12/ee/2fba0aecb52e7020e189f684148783aa0b9cfa3b3bfb0b400646eef70ad4/yarl-1.25.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:f074e8d4aa0a5798920ddb6de3d08b228c614ff3724c3e8bd7577f4bafea867b", size = 104041, upload-time = "2026-09-15T19:33:38.86Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/884beab53ed88c7247d1671972b5ef116f7351fe0c7e6de8c3558372cb16/yarl-1.25.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d42e7e3ca399555578b4d617e3a6ecf13371b3743a115995fa010c7bf341459", size = 116018, upload-time = "2026-09-15T19:33:44.265Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cc/1a91b685afb55cc18608443ace95280e96e263a97565811732b6788d3269/yarl-1.25.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aa4ed3dd308548f9e707d9caaf005d2d7f8c1e7868f858dfeb47fe76e16b391d", size = 107033, upload-time = "2026-09-15T19:33:46.45Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c1/58b379fcb1d68d907b7fcf75200c44321896509b2a6a74abbb4b19d864d2/yarl-1.25.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42a66563d8cc056ee32e6191e05097a7b2b3bc302e0bc3133daf8710eb18bd26", size = 123257, upload-time = "2026-09-15T19:33:48.631Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/1fe96cf5c2aeab10095e48f38585cf5a8451fb7253234822398e52aa5336/yarl-1.25.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98d370568f393215d605304cdb77b3d5539bd192c75b623c7304c42c8d6d8273", size = 126745, upload-time = "2026-09-15T19:33:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/ad/60/8674394ce43f4dadae573a1d6f451716438e9eab7d7fe8d643c673a32d85/yarl-1.25.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23bf5b403c879a54964e0feac7285688e04bb220074878d737d331522da0a5bf", size = 117255, upload-time = "2026-09-15T19:33:53.456Z" }, + { url = "https://files.pythonhosted.org/packages/2f/72/0faa30e02605d56127d42bb987dcc97da3863b7bf70b9bfbf5f739c05e30/yarl-1.25.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d45673badd08456d0340e9364eddafe1c53a9d2896424294de4d7dd71ad3ee57", size = 115166, upload-time = "2026-09-15T19:33:55.669Z" }, + { url = "https://files.pythonhosted.org/packages/8c/90/9a46eac564c437e128285c5c1d7bb385d268394e9209d84f6bf4a14471ef/yarl-1.25.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0136d640dfa9b0523853e411430a99f8a91eca85774c6420285a33b755bc6de3", size = 116082, upload-time = "2026-09-15T19:33:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/ad/38/4b1a686a3758878f93d2f1ea943f5a165f3555769cd16e761cfd0efdca17/yarl-1.25.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:59ba3a6e1aa8cfe5adf4bd270fd965db21955401b7ca6f1696010c55ed4daec2", size = 108048, upload-time = "2026-09-15T19:34:00.25Z" }, + { url = "https://files.pythonhosted.org/packages/da/14/f348eb967f31a58348612a2b93bd8a2ab664548e2b5e879cac7f592f7201/yarl-1.25.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:87796fedc3ba97ec14fab55acb48584276e6c1e4c1e89c422bda62c838e754a9", size = 122775, upload-time = "2026-09-15T19:34:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/ab/e9/4f7b79700f88cb9e8bb66f8b54f9bce1844c013a2c39fdc47112e9334c95/yarl-1.25.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:bd0912757081f89b107d6c00b2ff8a194401b0b87eadcf4481de2b865a8fd44f", size = 115096, upload-time = "2026-09-15T19:34:05.283Z" }, + { url = "https://files.pythonhosted.org/packages/cf/37/f9cb020331997d3eb887bd28d5410ecfd3d80bf163c23d7cec490d78dade/yarl-1.25.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:b51c159a9794633f5e0db7ecec7b2b6e3734eca1f5d17dc989ff3552a43ff78b", size = 120655, upload-time = "2026-09-15T19:34:07.382Z" }, + { url = "https://files.pythonhosted.org/packages/12/83/52fceb22891a41f168db7ec22fd1d81e06b6a0b8d9f70921bd3e785defd0/yarl-1.25.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:319e070a01db9920fb63761843f96a104c8e2b9427266731810dc1e22595b17c", size = 117488, upload-time = "2026-09-15T19:34:09.988Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5c/ce6c4ff1247fcbe4b33d462c23a097106d909b173fde7042bc52290466e2/yarl-1.25.1-cp315-cp315-win_amd64.whl", hash = "sha256:a2059a2d891bd156bc5184e7ab7a56e78a84dfcfdeac8c501b552533ad1c36ee", size = 103434, upload-time = "2026-09-15T19:34:12.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/766a906b0704fb26d52b19dc22bed48a8ba0544203b70dcf44da350e8194/yarl-1.25.1-cp315-cp315-win_arm64.whl", hash = "sha256:a78b50b4f7918a3de71105d5c0b93bbc57bb8339a4d03a9dfd449f9068e76f3d", size = 99155, upload-time = "2026-09-15T19:34:15.132Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d3/a1d09b32cb6ab14f66b44939f5b4255b8b9e747aef3974af1d5d80ccc2fd/yarl-1.25.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:b5402a340723fa7da00b5cff987ddab61276be6d11251ea71ae02bcac54890d8", size = 149284, upload-time = "2026-09-15T19:34:17.452Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/fe554d879692650bca70bfbc0df124e82e4d2bb7456f698c7756f1279a96/yarl-1.25.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:eda19ea5ee88742f47a2340816e6f2d40b53bed3ab5b69794769f36af9f35bb4", size = 106399, upload-time = "2026-09-15T19:34:21.474Z" }, + { url = "https://files.pythonhosted.org/packages/e1/4b/e7af56177ac8d40094c82d7728224c0b8472157d50d362e5fb3b014b2bc8/yarl-1.25.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:75baa6cf9b6d1c52f3e111a130e202fd8cf0a5b3a066c3f73d615e885092e4ec", size = 106968, upload-time = "2026-09-15T19:34:23.619Z" }, + { url = "https://files.pythonhosted.org/packages/da/4f/2df41fd738d46f23ef829ae8b4468d94bb6070038fc6dfab6165ed44fea8/yarl-1.25.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbcef5a9119ef653653132cccaf999b30a0af6f33bb0a4ba80bec30056868487", size = 114717, upload-time = "2026-09-15T19:34:25.879Z" }, + { url = "https://files.pythonhosted.org/packages/69/ea/002b66df53bbd1aed1c23358ff99c9bdc744fe3f4d2740e1b2fdd7192885/yarl-1.25.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7efc9f082dfed77c316edffa9deb52888e1bc6789171887cc1f68e06d65465c8", size = 105198, upload-time = "2026-09-15T19:34:28.204Z" }, + { url = "https://files.pythonhosted.org/packages/b1/7c/95c8bc0c8f97d71e59c94525ad60d76f5c57d3f2820f08137ca8b9f0542a/yarl-1.25.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe01645169a2112aa1d4ebc3e4c5f029c5c8f97adfc32e5d37c993b39a994d75", size = 120271, upload-time = "2026-09-15T19:34:30.5Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7a/6fe9da56ec77927baa669fd86c39c567ce6205bab53d581082c6744c8ae7/yarl-1.25.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1c557dfd5e3db046053a0bdc72261ade790ebe8e2c7a41b36b0ca1f14cb95f3", size = 123572, upload-time = "2026-09-15T19:34:32.73Z" }, + { url = "https://files.pythonhosted.org/packages/8b/83/35f222d17fa70a14c7c74fdf112ccf5515e0c2a87082b1f9b99f7693bf57/yarl-1.25.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ce4d6ccafb33d39bd78444612d14938ead674c25702ded2ee9c54a47735d225", size = 115228, upload-time = "2026-09-15T19:34:35.344Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/fbaaf619423578a7d898d0f226ae47bc1906c293865c416d83c17b828b0e/yarl-1.25.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80a063f8297fc796296f00f100be520f209b23dc98f93ce8eba6ee7122598209", size = 111618, upload-time = "2026-09-15T19:34:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/ba/78/7383278f1b3cf8e0496bd95b3281a7b09b89217b6b428db24c6b99b3deca/yarl-1.25.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:7cb414a73e21a7ab58254926073f2930cb22f5b4314ea4260a687e2b3fd4dce3", size = 114839, upload-time = "2026-09-15T19:34:40.099Z" }, + { url = "https://files.pythonhosted.org/packages/62/49/5506e5b6d29aab91bd845cc9016d88c3d3f81b81bc242b8100bdd5737825/yarl-1.25.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:85a18376073f8a39aa07be34f9fc77e2869aa72c55c441efdd2cf79a0407504d", size = 106212, upload-time = "2026-09-15T19:34:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/19877c193b7c5929f4b07118c18bbe390f3fadd0f59dd98c0cd12b31fa5c/yarl-1.25.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:77716e245c90f058466a05e6a465bb8600f767a8f4b18b4d40f3aff958e5f73c", size = 119985, upload-time = "2026-09-15T19:34:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6c/0a46fbbf9ecbcbd0cc20d2193394254b9e19817f22c814aab60f99847400/yarl-1.25.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:1e80dcf1446e1b080b1932b0d103c464a04112f5bc31f0f983ad418172063cde", size = 112081, upload-time = "2026-09-15T19:34:47.45Z" }, + { url = "https://files.pythonhosted.org/packages/ef/30/93f5d471230c74ccd06255d0842739f86551f937f9e63a5e947853c6244a/yarl-1.25.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:bdc8d8b8c22e9e43ac68316b5e6cf083dec537f4ec213cb4aa967b583bc3fa64", size = 116995, upload-time = "2026-09-15T19:34:49.972Z" }, + { url = "https://files.pythonhosted.org/packages/2b/80/c386593035ee3f9c6c6af0847b5578f2830c674794a9d7701b744a3ebd42/yarl-1.25.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbf531053a0935f2e871bcd4753f90313688772ff8c017f5ea402e315a78c1f", size = 115570, upload-time = "2026-09-15T19:34:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/38/02/eef443559563ef8f2e10469387b8b1e97cb5efee95b288a56da60801f7ee/yarl-1.25.1-cp315-cp315t-win_amd64.whl", hash = "sha256:b13b88747769537f3d32e89e3a735da10c0a9e35d7322928c701b5f93d3afffd", size = 106811, upload-time = "2026-09-15T19:34:54.935Z" }, + { url = "https://files.pythonhosted.org/packages/88/91/41e284ca2cf5211e05dae031d126a3668aea88fa759df56e7e35c6ad25ba/yarl-1.25.1-cp315-cp315t-win_arm64.whl", hash = "sha256:783dd1467083f4d3f7722ad6a313f24c173e7571372738fcb7a6e6d1ba48df25", size = 101804, upload-time = "2026-09-15T19:34:57.231Z" }, + { url = "https://files.pythonhosted.org/packages/54/22/318c7980066769c6bcd9221ed2248294f5698811da099013098c670565ed/yarl-1.25.1-py3-none-any.whl", hash = "sha256:681c758b0490f9e96b78e5fa8e8dc6e648e9185bb6eaebe73183c33ea0c445f3", size = 63617, upload-time = "2026-09-15T19:34:59.616Z" }, ] [[package]] From afcfcf256c95e36d563289ed072582540efc74db Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Tue, 20 Oct 2026 17:06:45 -0400 Subject: [PATCH 34/70] fix(flags): compare numeric string properties numerically (#1088) (cherry picked from commit 63b5dcca4ebaf3d42fee4cf6c9639e516dc2df4a) --- .../numeric-string-flag-comparisons.md | 5 + posthog/feature_flags.py | 61 ++--- posthog/test/test_feature_flags.py | 223 +++++++++++++++++- 3 files changed, 252 insertions(+), 37 deletions(-) create mode 100644 .sampo/changesets/numeric-string-flag-comparisons.md diff --git a/.sampo/changesets/numeric-string-flag-comparisons.md b/.sampo/changesets/numeric-string-flag-comparisons.md new file mode 100644 index 000000000..b544a8ee4 --- /dev/null +++ b/.sampo/changesets/numeric-string-flag-comparisons.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Fix local feature flag `gt`, `gte`, `lt`, and `lte` comparisons to compare numeric strings numerically rather than lexicographically. This can change which users match flags targeting numeric-string properties. Only complete, unpadded decimal strings and finite numbers are accepted: invalid properties no longer compare lexicographically, and invalid filter values allow remote evaluation fallback. diff --git a/posthog/feature_flags.py b/posthog/feature_flags.py index 87da025b5..7545306ea 100644 --- a/posthog/feature_flags.py +++ b/posthog/feature_flags.py @@ -643,6 +643,23 @@ def _is_truthy_property_value(value) -> bool: return False +_NUMERIC_STRING_PATTERN = re.compile( + r"[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?" +) + + +def _parse_numeric_value(value) -> float | None: + if isinstance(value, bool) or not isinstance(value, (str, int, float, Decimal)): + return None + if isinstance(value, str) and not _NUMERIC_STRING_PATTERN.fullmatch(value): + return None + try: + parsed = float(value) + except (ValueError, OverflowError): + return None + return parsed if math.isfinite(parsed) else None + + def match_property( property, property_values, property_matching_version: int = 1 ) -> bool: @@ -664,6 +681,21 @@ def match_property( override_value = property_values[key] + if operator in NUMERIC_OPERATORS: + parsed_value = _parse_numeric_value(value) + if parsed_value is None: + raise InconclusiveMatchError("The numeric condition is not a finite number") + parsed_override = _parse_numeric_value(override_value) + if parsed_override is None: + return False + if operator == "gt": + return parsed_override > parsed_value + if operator == "gte": + return parsed_override >= parsed_value + if operator == "lt": + return parsed_override < parsed_value + return parsed_override <= parsed_value + if ( operator not in NONE_VALUES_ALLOWED_OPERATORS and operator != "exact" @@ -730,35 +762,6 @@ def compute_exact_match(value, override_value): and re.compile(str(value)).search(str(override_value)) is None ) - if operator in ("gt", "gte", "lt", "lte"): - # :TRICKY: We adjust comparison based on the override value passed in, - # to make sure we handle both numeric and string comparisons appropriately. - def compare(lhs, rhs, operator): - if operator == "gt": - return lhs > rhs - elif operator == "gte": - return lhs >= rhs - elif operator == "lt": - return lhs < rhs - elif operator == "lte": - return lhs <= rhs - else: - raise ValueError(f"Invalid operator: {operator}") - - parsed_value = None - try: - parsed_value = float(value) - except Exception: - pass - - if parsed_value is not None and override_value is not None: - if isinstance(override_value, str): - return compare(override_value, str(value), operator) - else: - return compare(override_value, parsed_value, operator) - else: - return compare(str(override_value), str(value), operator) - if operator in ["is_date_before", "is_date_after"]: try: parsed_date = relative_date_parse_for_feature_flag_matching(str(value)) diff --git a/posthog/test/test_feature_flags.py b/posthog/test/test_feature_flags.py index a126a0092..374cb3259 100644 --- a/posthog/test/test_feature_flags.py +++ b/posthog/test/test_feature_flags.py @@ -3,6 +3,7 @@ import threading import unittest +from decimal import Decimal from unittest import mock from zoneinfo import ZoneInfo from dateutil import parser @@ -118,6 +119,105 @@ def test_missing_nested_cohort_always_requires_server_evaluation(self): ) +class TestNumericOrderingLocalEvaluation(unittest.TestCase): + def setUp(self): + self.client = Client(FAKE_TEST_API_KEY) + + def tearDown(self): + self.client.shutdown() + + @parameterized.expand([("get_feature_flag",), ("evaluate_flags",)]) + @mock.patch("posthog.client.flags") + @mock.patch.object(Client, "capture") + def test_numeric_ordering_and_remote_fallback(self, api, _capture, remote): + cases = ( + ("gt", 2, {"amount": "10"}, True, False), + ("lt", 30, {"amount": "100"}, False, False), + ("gte", "5", {"amount": "10"}, True, False), + ("lte", "5", {"amount": "10"}, False, False), + ("gt", "5", {"amount": "10px"}, False, False), + ("gt", "5", {"amount": None}, False, False), + ("gt", "5px", {"amount": "10"}, True, True), + ("gt", "5px", {"amount": None}, True, True), + ("gt", "5", {}, True, True), + ("gt", "2", {"amount": Decimal(10)}, True, False), + ("gte", "5", {"amount": Decimal(5)}, True, False), + ("lt", "5", {"amount": Decimal(2)}, True, False), + ("lte", "5", {"amount": Decimal(5)}, True, False), + ( + "gt", + "9007199254740992", + {"amount": Decimal(9007199254740993)}, + False, + False, + ), + ("gte", "0.1", {"amount": Decimal("0.1")}, True, False), + ("lte", "0", {"amount": Decimal("1e-400")}, True, False), + ("gt", "2", {"amount": Decimal("1e10000")}, False, False), + ("gt", "2", {"amount": Decimal("-1e10000")}, False, False), + ("gt", "2", {"amount": Decimal("NaN")}, False, False), + ("gt", "2", {"amount": Decimal("sNaN")}, False, False), + ("gt", "2", {"amount": Decimal("Infinity")}, False, False), + ("gt", "2", {"amount": Decimal("-Infinity")}, False, False), + ) + for operator, condition, properties, expected, fallback in cases: + for local_only in (False, True): + with self.subTest( + operator=operator, + condition=condition, + properties=properties, + local_only=local_only, + ): + self.client.feature_flags = [ + { + "id": 1, + "key": "numeric-flag", + "active": True, + "filters": { + "groups": [ + { + "properties": [ + { + "key": "amount", + "operator": operator, + "value": condition, + "type": "person", + } + ], + "rollout_percentage": 100, + } + ] + }, + } + ] + remote.reset_mock() + remote.return_value = { + "flags": {"numeric-flag": {"enabled": True, "variant": None}} + } + kwargs = { + "person_properties": properties, + "only_evaluate_locally": local_only, + } + if api == "get_feature_flag": + result = self.client.get_feature_flag( + "numeric-flag", + "user-1", + send_feature_flag_events=False, + **kwargs, + ) + else: + result = self.client.evaluate_flags( + "user-1", **kwargs + ).get_flag("numeric-flag") + if fallback and local_only: + self.assertIsNone(result) + else: + self.assertIs(result, expected) + self.assertEqual( + remote.call_count, int(fallback and not local_only) + ) + + class TestLocalEvaluation(unittest.TestCase): @classmethod def setUpClass(cls): @@ -5625,16 +5725,121 @@ def test_match_properties_math_operators(self): property_e = self.property(key="key", value="30", operator="lt") self.assertTrue(match_property(property_e, {"key": "29"})) - # depending on the type of override, we adjust type comparison - self.assertTrue(match_property(property_e, {"key": "100"})) + self.assertFalse(match_property(property_e, {"key": "100"})) self.assertFalse(match_property(property_e, {"key": 100})) property_f = self.property(key="key", value="123aloha", operator="gt") - self.assertFalse(match_property(property_f, {"key": "123"})) - self.assertFalse(match_property(property_f, {"key": 122})) + for actual in ("123", 122, 129): + with self.assertRaises(InconclusiveMatchError): + match_property(property_f, {"key": actual}) + + @parameterized.expand( + [ + ("gt", "10", 2, True), + ("lt", "100", 30, False), + ("gte", "10", "5", True), + ("lte", "10", "5", False), + ("gt", "+1.e1", "+.5e+1", True), + ("lt", "-1.25E+2", "-12.5", True), + ("gte", "-.5", "-5e-1", True), + ("lte", "1e-400", 0, True), + ("gte", "1.7976931348623157e308", 1e308, True), + ("gt", "9007199254740993", "9007199254740992", False), + ("gt", 9007199254740993, 9007199254740992, False), + ("gt", Decimal(9007199254740993), "9007199254740992", False), + ("gte", Decimal("0.1"), "0.1", True), + ("lte", Decimal("1e-400"), "0", True), + ] + ) + def test_numeric_ordering_regressions(self, operator, actual, condition, expected): + for version in (1, 2): + with self.subTest(version=version): + self.assertEqual( + match_property( + self.property("key", condition, operator), + {"key": actual}, + property_matching_version=version, + ), + expected, + ) - # this turns into a string comparison - self.assertTrue(match_property(property_f, {"key": 129})) + def test_numeric_ordering_operand_types_and_boundaries(self): + for operator, expected_results in ( + ("gt", (False, False, True)), + ("gte", (False, True, True)), + ("lt", (True, False, False)), + ("lte", (True, True, False)), + ): + for condition in (5, 5.0, "5"): + prop = self.property("key", condition, operator) + for actuals, expected in zip( + ( + (2, 2.0, "2", Decimal(2)), + (5, 5.0, "5", Decimal(5)), + (10, 10.0, "10", Decimal(10)), + ), + expected_results, + ): + for actual in actuals: + with self.subTest( + operator=operator, condition=condition, actual=actual + ): + self.assertEqual( + match_property(prop, {"key": actual}), expected + ) + + def test_numeric_ordering_invalid_operands(self): + invalid_values = ( + "", + "abc", + "10px", + " 10", + "10 ", + "10\n", + "1_0", + "1,0", + "1e", + "0x10", + "١٠", + "NaN", + "Infinity", + "-inf", + "1e309", + float("nan"), + float("inf"), + float("-inf"), + Decimal("1e10000"), + Decimal("-1e10000"), + Decimal("NaN"), + Decimal("sNaN"), + Decimal("Infinity"), + Decimal("-Infinity"), + 10**400, + True, + False, + None, + [], + [10], + {}, + {"value": 10}, + b"10", + ) + for operator in ("gt", "gte", "lt", "lte"): + for invalid in invalid_values: + with self.subTest(operator=operator, invalid=invalid): + for condition in (5, "5"): + prop = self.property("key", condition, operator) + self.assertFalse(match_property(prop, {"key": invalid})) + prop = self.property("key", invalid, operator) + for actual in (10, "10", None): + with self.assertRaises(InconclusiveMatchError): + match_property(prop, {"key": actual}) + for condition in (5, "5"): + prop = self.property("key", condition, operator) + with self.assertRaises(InconclusiveMatchError): + match_property(prop, {}) + with self.assertRaises(InconclusiveMatchError): + match_property({"key": "key", "operator": operator}, {"key": 10}) def test_match_property_date_operators(self): property_a = self.property( @@ -5889,10 +6094,12 @@ def test_none_property_value_with_all_operators(self): self.assertFalse(match_property(property_f, {"key": None})) property_g = self.property(key="key", value="xyz", operator="gte") - self.assertFalse(match_property(property_g, {"key": None})) + with self.assertRaises(InconclusiveMatchError): + match_property(property_g, {"key": None}) property_h = self.property(key="key", value="Oo", operator="lte") - self.assertFalse(match_property(property_h, {"key": None})) + with self.assertRaises(InconclusiveMatchError): + match_property(property_h, {"key": None}) property_i = self.property( key="key", value="2022-05-01", operator="is_date_before" From 30263c6d0fc52176e6e7c2324ff282da10fad262 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:59:03 +0000 Subject: [PATCH 35/70] chore: Release v7.73.2 [skip ci] (cherry picked from commit cb7580e2b884ca99b0693913fc822d2da1559701) --- .sampo/changesets/numeric-string-flag-comparisons.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/numeric-string-flag-comparisons.md diff --git a/.sampo/changesets/numeric-string-flag-comparisons.md b/.sampo/changesets/numeric-string-flag-comparisons.md deleted file mode 100644 index b544a8ee4..000000000 --- a/.sampo/changesets/numeric-string-flag-comparisons.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Fix local feature flag `gt`, `gte`, `lt`, and `lte` comparisons to compare numeric strings numerically rather than lexicographically. This can change which users match flags targeting numeric-string properties. Only complete, unpadded decimal strings and finite numbers are accepted: invalid properties no longer compare lexicographically, and invalid filter values allow remote evaluation fallback. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 8b582d72a..a38945df1 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.111 — 2026-10-20 + +### Patch changes + +- Updated dependencies: posthog@7.73.2 + ## 0.1.110 — 2026-10-20 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index d1203da8f..15518fae6 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.110" +version = "0.1.111" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 9629faa88..49618a118 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.73.2 — 2026-10-20 + +### Patch changes + +- [63b5dcc](https://github.com/posthog/posthog-python/commit/63b5dcca4ebaf3d42fee4cf6c9639e516dc2df4a) Fix local feature flag `gt`, `gte`, `lt`, and `lte` comparisons to compare numeric strings numerically rather than lexicographically. This can change which users match flags targeting numeric-string properties. Only complete, unpadded decimal strings and finite numbers are accepted: invalid properties no longer compare lexicographically, and invalid filter values allow remote evaluation fallback. — Thanks @dustinbyrne! + ## 7.73.1 — 2026-10-20 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index ab107779f..fecfeedf6 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.73.1" +VERSION = "7.73.2" diff --git a/pyproject.toml b/pyproject.toml index 3d645461c..7db0d68e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.73.1" +version = "7.73.2" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index e5bcc9f99..6912e02e7 100644 --- a/uv.lock +++ b/uv.lock @@ -2533,7 +2533,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.110" +version = "0.1.111" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2863,7 +2863,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.1" +version = "7.73.2" source = { editable = "." } dependencies = [ { name = "distro" }, From 578256a464cb1f2ea1d96227169bab616e2f7ed3 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:59:08 +0000 Subject: [PATCH 36/70] Update generated references (cherry picked from commit 1222ac7f269b1acc189a5f9284fb74bafdc2f572) --- .../posthog-python-references-7.73.2.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.73.2.json diff --git a/references/posthog-python-references-7.73.2.json b/references/posthog-python-references-7.73.2.json new file mode 100644 index 000000000..0df272044 --- /dev/null +++ b/references/posthog-python-references-7.73.2.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.73.2", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 9c588f586..0df272044 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.73.1", + "version": "7.73.2", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 170a49fb7b36dc091b53210ff0ab1e8ae30a4401 Mon Sep 17 00:00:00 2001 From: mosafariuk Date: Wed, 21 Oct 2026 11:00:24 +0100 Subject: [PATCH 37/70] fix(ai): keep the openai.Stream API on sync OpenAI streams (#1062) Sync chat completions and Responses streams returned a bare generator, so `with`, `close()` and attributes such as `.response` were lost. Wrap them with _StreamWrapper, as #804 did for Anthropic and #645 did for async. Co-authored-by: Dustin Byrne (cherry picked from commit f70b3cc3f0c5054f35ffc974b50005431aea511d) --- .sampo/changesets/openai-sync-stream-api.md | 5 + posthog/ai/openai/openai.py | 5 +- posthog/ai/stream.py | 4 +- posthog/test/ai/openai/test_openai.py | 119 +++++++++++++++++++- posthog/test/ai/utils.py | 23 ++++ 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 .sampo/changesets/openai-sync-stream-api.md diff --git a/.sampo/changesets/openai-sync-stream-api.md b/.sampo/changesets/openai-sync-stream-api.md new file mode 100644 index 000000000..8d70d9284 --- /dev/null +++ b/.sampo/changesets/openai-sync-stream-api.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Keep the `openai.Stream` API on sync OpenAI chat completions and Responses streams, so `with`, `close()` and attributes such as `.response` work as they do without PostHog. diff --git a/posthog/ai/openai/openai.py b/posthog/ai/openai/openai.py index e2cbf7fb6..0a8da0e58 100644 --- a/posthog/ai/openai/openai.py +++ b/posthog/ai/openai/openai.py @@ -33,6 +33,7 @@ _ResponsesStreamState, _build_streaming_event_data, ) +from ..stream import _StreamWrapper from ._embeddings import _capture_embedding_event from .wrapper_utils import ( _OpenAIWrapperResource, @@ -185,7 +186,7 @@ def generator(): time.time() - start_time, ) - return generator() + return _StreamWrapper(generator(), stream=response) def _capture_streaming_event( self, @@ -403,7 +404,7 @@ def generator(): time.time() - start_time, ) - return generator() + return _StreamWrapper(generator(), stream=response) def _capture_streaming_event( self, diff --git a/posthog/ai/stream.py b/posthog/ai/stream.py index 2499f6e68..8744c6177 100644 --- a/posthog/ai/stream.py +++ b/posthog/ai/stream.py @@ -32,7 +32,9 @@ def close(self) -> None: try: self._generator.close() finally: - self._stream.close() + close = getattr(self._stream, "close", None) + if close is not None: + close() def __getattr__(self, name: str) -> Any: if name.startswith("_"): diff --git a/posthog/test/ai/openai/test_openai.py b/posthog/test/ai/openai/test_openai.py index 21f40bf6e..95fdc22b0 100644 --- a/posthog/test/ai/openai/test_openai.py +++ b/posthog/test/ai/openai/test_openai.py @@ -36,7 +36,11 @@ from posthog.ai.openai import OpenAI from posthog.ai.openai.openai_async import AsyncOpenAI from posthog.ai.openai.wrapper_utils import reset_fallback_warnings - from posthog.test.ai.utils import RecordingAsyncStream, make_response_usage + from posthog.test.ai.utils import ( + RecordingAsyncStream, + RecordingStream, + make_response_usage, + ) OPENAI_AVAILABLE = True except ImportError: @@ -2422,6 +2426,119 @@ async def mock_create(self, **kwargs): assert mock_client.capture_ai.call_count == 1 +def test_chat_streaming_supports_with_and_proxies_provider_stream( + mock_client, streaming_tool_call_chunks +): + """Sync chat completions stream=True must keep the `openai.Stream` API: + `with`, and attributes such as `.response`.""" + source = RecordingStream(streaming_tool_call_chunks) + + with patch( + "openai.resources.chat.completions.Completions.create", return_value=source + ): + client = OpenAI(api_key="test-key", posthog_client=mock_client) + + response = client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": "Hi"}], + stream=True, + posthog_distinct_id="test-id", + ) + + assert response.response == "provider-response" + with response as stream: + chunks = list(stream) + + assert chunks == streaming_tool_call_chunks + assert source.closed is True + assert mock_client.capture_ai.call_count == 1 + call_args = mock_client.capture_ai.call_args[1] + props = call_args["properties"] + assert call_args["event"] == "$ai_generation" + assert props["$ai_provider"] == "openai" + assert props["$ai_model"] == "gpt-4" + + +def test_responses_streaming_supports_with_and_proxies_provider_stream(mock_client): + """Sync responses stream=True must keep the `openai.Stream` API.""" + from unittest.mock import MagicMock + + chunk = MagicMock() + chunk.type = "response.text.delta" + chunk.text = "hello" + source = RecordingStream([chunk]) + + with patch("openai.resources.responses.Responses.create", return_value=source): + client = OpenAI(api_key="test-key", posthog_client=mock_client) + + response = client.responses.create( + model="gpt-4o-mini", + input=[{"role": "user", "content": "Hi"}], + stream=True, + posthog_distinct_id="test-id", + ) + + assert response.response == "provider-response" + with response as stream: + received = list(stream) + + assert received == [chunk] + assert source.closed is True + assert mock_client.capture_ai.call_count == 1 + + +def test_chat_streaming_early_exit_closes_provider_stream( + mock_client, streaming_tool_call_chunks +): + """Breaking out of a sync stream early must close the underlying provider + stream (release the HTTP connection) and still capture the event.""" + source = RecordingStream(streaming_tool_call_chunks) + + with patch( + "openai.resources.chat.completions.Completions.create", return_value=source + ): + client = OpenAI(api_key="test-key", posthog_client=mock_client) + + response = client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": "Hi"}], + stream=True, + posthog_distinct_id="test-id", + ) + + with response as stream: + for _ in stream: + break + + assert source.closed is True + assert mock_client.capture_ai.call_count == 1 + + +def test_chat_streaming_close_closes_provider_stream( + mock_client, streaming_tool_call_chunks +): + """Calling `close()` mid-stream, outside a `with` block, must close the + provider stream and still capture the event.""" + source = RecordingStream(streaming_tool_call_chunks) + + with patch( + "openai.resources.chat.completions.Completions.create", return_value=source + ): + client = OpenAI(api_key="test-key", posthog_client=mock_client) + + response = client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": "Hi"}], + stream=True, + posthog_distinct_id="test-id", + ) + next(response) + response.close() + + assert source.closed is True + assert mock_client.capture_ai.call_count == 1 + + def test_multimodal_client_skips_media_redaction(mock_client, mock_openai_response): mock_client.enable_full_ai_capture = True image = "data:image/jpeg;base64," + "A" * 64 diff --git a/posthog/test/ai/utils.py b/posthog/test/ai/utils.py index e1ad48f7b..9f27c1f38 100644 --- a/posthog/test/ai/utils.py +++ b/posthog/test/ai/utils.py @@ -41,6 +41,29 @@ def build(model_cls, known): ) +class RecordingStream: + """Mock provider sync stream that is iterable and records when closed. + + Mirrors the real ``openai.Stream``: it supports ``for`` and exposes + ``close()`` plus a ``response`` attribute, so tests can assert both + iteration and that the underlying stream is closed on context exit. + """ + + def __init__(self, items): + self._items = iter(items) + self.closed = False + self.response = "provider-response" + + def __iter__(self): + return self + + def __next__(self): + return next(self._items) + + def close(self): + self.closed = True + + class RecordingAsyncStream: """Mock provider async stream that is iterable and records when closed. From 5abb26a44ef5e4ff746fd7aee2b2bf4aa64c3864 Mon Sep 17 00:00:00 2001 From: alexcastgonz <82875882+pcbeingused333@users.noreply.github.com> Date: Wed, 21 Oct 2026 07:43:05 -0400 Subject: [PATCH 38/70] fix(ai): take cumulative Anthropic stream usage from message_delta (#1074) Anthropic's message_delta usage is cumulative. With server tools (web search, web fetch, code execution) its input and cache counts exceed message_start's, but the stream accumulator only recorded message_start's input and cache counts, so streamed generations under-reported input tokens and cache writes. Keep the larger of the two for each count. Co-authored-by: Claude Opus 5.5 (cherry picked from commit 57d160712e8d01750031c953bea093065d217128) --- .../cumulative-anthropic-stream-usage.md | 5 ++ posthog/ai/anthropic/_anthropic_stream.py | 25 ++++++ posthog/test/ai/anthropic/test_anthropic.py | 83 +++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 .sampo/changesets/cumulative-anthropic-stream-usage.md diff --git a/.sampo/changesets/cumulative-anthropic-stream-usage.md b/.sampo/changesets/cumulative-anthropic-stream-usage.md new file mode 100644 index 000000000..6e06e0513 --- /dev/null +++ b/.sampo/changesets/cumulative-anthropic-stream-usage.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Streamed Anthropic generations now take the input and cache token counts from the final `message_delta` usage, which is cumulative. With server tools such as web search, those counts grow past the `message_start` values, so streamed calls under-reported input tokens and cache writes. diff --git a/posthog/ai/anthropic/_anthropic_stream.py b/posthog/ai/anthropic/_anthropic_stream.py index e08f6f65e..ff3fbe0b8 100644 --- a/posthog/ai/anthropic/_anthropic_stream.py +++ b/posthog/ai/anthropic/_anthropic_stream.py @@ -26,9 +26,34 @@ def __init__(self) -> None: # web_search_tool_result, ...), so keep a list that lines up with it. self._blocks_by_index: List[StreamingContentBlock] = [] + def _apply_cumulative_input_usage(self, usage: Any) -> None: + # Usage on message_delta is cumulative. With server tools (web search, + # web fetch, code execution) its input and cache counts grow past + # message_start's, which is all the per-event merge records for them. + # The totals never shrink, so keep the larger value; a field the event + # omits leaves message_start's count in place. + input_tokens = getattr(usage, "input_tokens", None) + if isinstance(input_tokens, int): + self.usage_stats["input_tokens"] = max( + self.usage_stats.get("input_tokens") or 0, input_tokens + ) + cache_creation = getattr(usage, "cache_creation_input_tokens", None) + if isinstance(cache_creation, int): + self.usage_stats["cache_creation_input_tokens"] = max( + self.usage_stats.get("cache_creation_input_tokens") or 0, + cache_creation, + ) + cache_read = getattr(usage, "cache_read_input_tokens", None) + if isinstance(cache_read, int): + self.usage_stats["cache_read_input_tokens"] = max( + self.usage_stats.get("cache_read_input_tokens") or 0, cache_read + ) + def consume(self, event: Any) -> None: event_usage = extract_anthropic_usage_from_event(event) merge_usage_stats(self.usage_stats, event_usage) + if getattr(event, "type", None) == "message_delta": + self._apply_cumulative_input_usage(getattr(event, "usage", None)) if getattr(event, "type", None) == "content_block_start": block, tool = handle_anthropic_content_block_start(event) diff --git a/posthog/test/ai/anthropic/test_anthropic.py b/posthog/test/ai/anthropic/test_anthropic.py index 2774933aa..13fbccd65 100644 --- a/posthog/test/ai/anthropic/test_anthropic.py +++ b/posthog/test/ai/anthropic/test_anthropic.py @@ -824,6 +824,89 @@ async def mock_async_create(**kwargs): ) +def anthropic_stream_with_server_tool_usage(): + # With server tools, message_delta reports cumulative usage that exceeds + # message_start's (values from a recorded web search stream). + return [ + RawMessageStartEvent( + type="message_start", + message=Message( + id="msg_1", + type="message", + role="assistant", + model="claude-haiku-4-5", + content=[], + stop_reason=None, + stop_sequence=None, + usage=Usage( + input_tokens=2247, + output_tokens=26, + cache_creation_input_tokens=0, + cache_read_input_tokens=0, + ), + ), + ), + RawMessageDeltaEvent( + type="message_delta", + delta=Delta(stop_reason="end_turn", stop_sequence=None), + usage=MessageDeltaUsage( + input_tokens=2254, + output_tokens=110, + cache_creation_input_tokens=17269, + cache_read_input_tokens=0, + ), + ), + RawMessageStopEvent(type="message_stop"), + ] + + +def assert_cumulative_delta_usage(props): + assert props["$ai_input_tokens"] == 2254 + assert props["$ai_output_tokens"] == 110 + assert props["$ai_cache_creation_input_tokens"] == 17269 + assert props["$ai_cache_read_input_tokens"] == 0 + + +def test_streaming_takes_cumulative_message_delta_usage(mock_client): + with patch( + "anthropic.resources.Messages.create", + return_value=iter(anthropic_stream_with_server_tool_usage()), + ): + client = Anthropic(api_key="test-key", posthog_client=mock_client) + response = client.messages.create( + model="claude-haiku-4-5", + messages=[{"role": "user", "content": "Hello"}], + stream=True, + ) + list(response) + + assert_cumulative_delta_usage(mock_client.capture_ai.call_args.kwargs["properties"]) + + +@pytest.mark.asyncio +async def test_streaming_takes_cumulative_message_delta_usage_async(mock_client): + async def mock_async_stream(): + for event in anthropic_stream_with_server_tool_usage(): + yield event + + async def mock_async_create(**kwargs): + return mock_async_stream() + + with patch( + "anthropic.resources.messages.AsyncMessages.create", + side_effect=mock_async_create, + ): + client = AsyncAnthropic(api_key="test-key", posthog_client=mock_client) + response = await client.messages.create( + model="claude-haiku-4-5", + messages=[{"role": "user", "content": "Hello"}], + stream=True, + ) + [event async for event in response] + + assert_cumulative_delta_usage(mock_client.capture_ai.call_args.kwargs["properties"]) + + def test_anthropic_bedrock_preserves_cache_creation_ttl_breakdown( mock_client, mock_anthropic_response_with_cache_ttl ): From 974435310febf5974314abb2587ab0bed9b4854d Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 13:12:55 +0000 Subject: [PATCH 39/70] chore: Release v7.73.3 [skip ci] (cherry picked from commit 24c6722fb3a6317ea41917400c148ca44f64cc43) --- .sampo/changesets/cumulative-anthropic-stream-usage.md | 5 ----- .sampo/changesets/openai-sync-stream-api.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 7 +++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 8 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 .sampo/changesets/cumulative-anthropic-stream-usage.md delete mode 100644 .sampo/changesets/openai-sync-stream-api.md diff --git a/.sampo/changesets/cumulative-anthropic-stream-usage.md b/.sampo/changesets/cumulative-anthropic-stream-usage.md deleted file mode 100644 index 6e06e0513..000000000 --- a/.sampo/changesets/cumulative-anthropic-stream-usage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Streamed Anthropic generations now take the input and cache token counts from the final `message_delta` usage, which is cumulative. With server tools such as web search, those counts grow past the `message_start` values, so streamed calls under-reported input tokens and cache writes. diff --git a/.sampo/changesets/openai-sync-stream-api.md b/.sampo/changesets/openai-sync-stream-api.md deleted file mode 100644 index 8d70d9284..000000000 --- a/.sampo/changesets/openai-sync-stream-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Keep the `openai.Stream` API on sync OpenAI chat completions and Responses streams, so `with`, `close()` and attributes such as `.response` work as they do without PostHog. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index a38945df1..eae14033a 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.112 — 2026-10-21 + +### Patch changes + +- Updated dependencies: posthog@7.73.3 + ## 0.1.111 — 2026-10-20 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 15518fae6..92d376079 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.111" +version = "0.1.112" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 49618a118..ef5cff2d4 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,12 @@ # posthog +## 7.73.3 — 2026-10-21 + +### Patch changes + +- [57d1607](https://github.com/posthog/posthog-python/commit/57d160712e8d01750031c953bea093065d217128) Streamed Anthropic generations now take the input and cache token counts from the final `message_delta` usage, which is cumulative. With server tools such as web search, those counts grow past the `message_start` values, so streamed calls under-reported input tokens and cache writes. — Thanks @pcbeingused333 for your first contribution 🎉! +- [f70b3cc](https://github.com/posthog/posthog-python/commit/f70b3cc3f0c5054f35ffc974b50005431aea511d) Keep the `openai.Stream` API on sync OpenAI chat completions and Responses streams, so `with`, `close()` and attributes such as `.response` work as they do without PostHog. — Thanks @mosafariuk for your first contribution 🎉! + ## 7.73.2 — 2026-10-20 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index fecfeedf6..94c1d369b 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.73.2" +VERSION = "7.73.3" diff --git a/pyproject.toml b/pyproject.toml index 7db0d68e6..f36cef857 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.73.2" +version = "7.73.3" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 6912e02e7..bf64fcfc8 100644 --- a/uv.lock +++ b/uv.lock @@ -2533,7 +2533,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.111" +version = "0.1.112" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2863,7 +2863,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.2" +version = "7.73.3" source = { editable = "." } dependencies = [ { name = "distro" }, From 21be61ebf2ceac12e2dacec29af384fff0f86f3b Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 13:13:00 +0000 Subject: [PATCH 40/70] Update generated references (cherry picked from commit bf873523c700d9940c8ec86b677d2bd4904dfa55) --- .../posthog-python-references-7.73.3.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.73.3.json diff --git a/references/posthog-python-references-7.73.3.json b/references/posthog-python-references-7.73.3.json new file mode 100644 index 000000000..973a24408 --- /dev/null +++ b/references/posthog-python-references-7.73.3.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.73.3", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 0df272044..973a24408 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.73.2", + "version": "7.73.3", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From bd5bbfc6893e5c2097a03a116a1d808727a8667c Mon Sep 17 00:00:00 2001 From: Radu Raicea Date: Wed, 21 Oct 2026 10:38:06 -0400 Subject: [PATCH 41/70] feat(llma): add datasets to offline evaluations (#1090) * feat(llma): add datasets to offline evaluations * chore(llma): share evaluation request and response helpers * fix(llma): address dataset sdk review feedback (cherry picked from commit b8879a7550e1bc2728bb5d23d8ddb215ba3602a7) --- .sampo/changesets/ai-evaluation-datasets.md | 5 + .../example-offline-evaluations/README.md | 163 +++- examples/example-offline-evaluations/main.py | 93 +- posthog/ai/evaluations/__init__.py | 24 +- posthog/ai/evaluations/_async_datasets.py | 443 +++++++++ posthog/ai/evaluations/_client.py | 9 +- .../ai/evaluations/_dataset_serialization.py | 251 ++++++ posthog/ai/evaluations/_dataset_types.py | 111 +++ posthog/ai/evaluations/_datasets.py | 436 +++++++++ posthog/ai/evaluations/_scorers.py | 52 +- posthog/ai/evaluations/_serialization.py | 49 +- posthog/ai/evaluations/_tags.py | 14 +- posthog/ai/evaluations/_types.py | 40 + posthog/test/ai/test_evaluations_datasets.py | 838 ++++++++++++++++++ posthog/test/ai/test_evaluations_scorers.py | 14 +- references/public_api_snapshot.txt | 100 +++ 16 files changed, 2570 insertions(+), 72 deletions(-) create mode 100644 .sampo/changesets/ai-evaluation-datasets.md create mode 100644 posthog/ai/evaluations/_async_datasets.py create mode 100644 posthog/ai/evaluations/_dataset_serialization.py create mode 100644 posthog/ai/evaluations/_dataset_types.py create mode 100644 posthog/ai/evaluations/_datasets.py create mode 100644 posthog/test/ai/test_evaluations_datasets.py diff --git a/.sampo/changesets/ai-evaluation-datasets.md b/.sampo/changesets/ai-evaluation-datasets.md new file mode 100644 index 000000000..22d689b31 --- /dev/null +++ b/.sampo/changesets/ai-evaluation-datasets.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +Manage AI observability datasets and items through `OfflineEvaluations.datasets` and `AsyncOfflineEvaluations.datasets`, including history, tags, and archive/restore operations. Pin a dataset snapshot for lazy, consistent reads and use `EvaluationItem.from_dataset_item()` to preserve case provenance across offline experiments and scorers. Item creates with a caller-supplied `client_item_id` support safe retries; updates use explicit version checks. diff --git a/examples/example-offline-evaluations/README.md b/examples/example-offline-evaluations/README.md index 279fe4e70..7da7dd1c8 100644 --- a/examples/example-offline-evaluations/README.md +++ b/examples/example-offline-evaluations/README.md @@ -1,6 +1,6 @@ # Offline evaluations -Upload evaluations you have already run, manage reusable scorers, and explicitly finish an experiment. The SDK returns server acknowledgments for every operation. It does not execute your application or judges, create traces, or upload in the background. +Upload evaluations you have already run, manage reusable scorers and datasets, and explicitly finish an experiment. The SDK returns server acknowledgments for every operation. It does not execute your application or judges, create traces, or upload in the background. ## Credentials and setup @@ -11,11 +11,15 @@ Offline evaluations must be enabled for your PostHog project. Use the project's | Create experiments, upload results, complete/fail | Personal API key or project secret key with `offline_evaluation_ingestion:write` | | Fetch scorers and versions | Personal API key with `llm_analytics:read` | | Create/update scorers and create versions | Personal API key with `llm_analytics:write` | +| Fetch datasets, items, and history | Personal API key with `dataset:read` | +| Create/update/archive/restore datasets and items | Personal API key with `dataset:write` | | Read experiment tags | Personal API key with `evaluation:read` | | Replace experiment tags | Personal API key with `evaluation:write` | A personal key can cover both scorer management and uploads. Project secret keys can upload using a known scorer-version UUID without scorer read access. All operations use the explicit project/environment; scorer names are not unique. +Dataset operations also require the datasets feature to be enabled. Dataset reads, scorer reads, and experiment uploads use their own scopes; an upload-only credential cannot fetch a dataset. Keep personal keys in server-side scripts or CI secrets. + From this repository's root: ```bash @@ -85,6 +89,163 @@ EvaluationItem(input=None) # Payload contains a null input. The client context manager releases connections. Call `complete()` explicitly after uploads succeed, or `fail()` when you deliberately want to close the experiment as failed. Neither exceptions nor async cancellation automatically close an experiment. Expected counts include every outcome status; the server checks them on completion. +## Datasets and reproducible evaluations + +Use `evaluations.datasets` to manage PostHog-hosted datasets with the same client configuration as scorers and experiments. Dataset names are unique within a project; keep the returned UUID for subsequent operations. + +Provision a dataset once with a personal key that has `dataset:write`: + +```python +dataset = evaluations.datasets.create( + name="Capital city regression cases", + description="Cases for the offline evaluation example", + tags=["regression"], +) +case = evaluations.datasets.create_item( + dataset.id, + client_item_id="capital-france", + input="Capital of France?", + expected_output="Paris", + metadata={"category": "geography"}, +) +print(dataset.id) +``` + +An identical item create with the same `client_item_id` returns the existing active item. Reusing that key with different current content, or for an archived item, raises `EvaluationAPIError` with `code="client_item_id_conflict"`. Choose a stable key per case and retain it across process restarts. Creating the dataset itself is not idempotent; keep its ID instead of provisioning it on each evaluation run. + +Pin both the dataset and scorer before running your application: + +```python +from posthog.ai.evaluations import EvaluationItem, OfflineEvaluations + +def capital_answer(question): + return {"Capital of France?": "Paris", "Capital of Italy?": "Rome"}.get( + question, "I don't know" + ) + +with OfflineEvaluations(project_id=123, secret_key=personal_api_key) as evaluations: + snapshot = evaluations.datasets.snapshot(dataset_id) # Resolve latest once. + scorer = evaluations.scorers.get(scorer_id) # A boolean exact-match scorer. + version_id = scorer.current_version_id + experiment = evaluations.create_experiment( + name="Capital city regression", + dataset_revision_id=snapshot.revision_id, + application_version="your-commit-sha", + run_source="ci", + ) + + for case in snapshot.iter_items(): + output = capital_answer(case.input) + item = EvaluationItem.from_dataset_item(case, output=output) + if case.expected_output is None: + experiment.upload_result( + item=item, scorer_version_id=version_id, status="not_applicable", + ) + else: + experiment.upload_result( + item=item, scorer_version_id=version_id, + value=output == case.expected_output, + ) + + experiment.complete() +``` + +This example uses string inputs. Replace `capital_answer` and the equality check with your own application and judge. The SDK does not run scorer definitions. For multiple scorers, reuse the same `EvaluationItem` and upload one result per scorer-version UUID. For independent trials, call `from_dataset_item` again and pass a distinct `trial`, such as `trial="2"`; each call generates a new execution UUID. The helper defaults `case_key` to `client_item_id`, falling back to the stable dataset item UUID, and accepts an explicit override. + +`from_dataset_item` copies input, expected output, metadata, and immutable item provenance. It never uses `source_output` as a new execution's output or expected answer, and never uses the original source trace as the new application's trace. Pass `application_trace_id` explicitly for the new execution. Omit `output` if execution failed before producing one, then upload an error outcome. Omitted output differs from `output=None`. + +### Snapshot and pagination behavior + +- `snapshot(dataset_id, revision=12)` selects a historical **number**. The returned `revision_id` is the **UUID** to pass to `create_experiment`. The backend derives the remaining hosted-dataset identifiers from that UUID. +- Every item request uses the pinned revision, even if another process edits or archives items during iteration. `DatasetItem.dataset_revision_id` identifies the revision that introduced that item version; it can differ from the snapshot's revision ID. Do not use it as the experiment's revision. +- `snapshot()` fetches metadata only. `snapshot.iter_items(page_size=25)` lazily fetches active items, one page at a time. Keep the client open. Repeating iteration starts again at the first page without caching; read errors propagate rather than silently returning a partial dataset. +- A new dataset has no revision until its first item is added, so `snapshot()` raises `ValueError`. An existing revision with zero active items yields an empty iterator. Archived datasets remain readable. +- `snapshot.dataset` contains current descriptive metadata observed when the snapshot was resolved. Names, descriptions, tags, and dataset metadata are not historical item content. + +For explicit paging, each `list*` method returns typed `results`, `count`, and `next_offset`. Continue with the same filters until `next_offset is None`. Dataset/revision pages allow at most 100 entries, item pages 25, and item-history pages 100. `list_items` without a revision reads live state on each request; use a snapshot for an evaluation run. A historical snapshot may make multiple metadata requests to find its revision UUID. + +| Method | Purpose | +| --- | --- | +| `list(search=..., tags=..., tag_match="any", archived=False, order_by="-created_at")` | Find datasets; `archived=True` selects archived datasets only | +| `get(dataset_id)` | Read current dataset metadata and revision references | +| `create(name=..., description=..., metadata=..., tags=...)` | Create an empty dataset | +| `update(dataset_id, name=..., description=..., metadata=..., tags=...)` | Replace supplied metadata fields without creating an item revision | +| `archive(dataset_id)` / `restore(dataset_id)` | Change dataset archive state; restore leaves individual item states unchanged | +| `list_revisions(dataset_id)` | Read revision history, newest first | +| `list_items(dataset_id, revision=..., archived=False)` | Read one page of current or historical items | +| `get_item(item_id, revision=...)` | Read one stable item at the current or selected dataset revision | +| `create_item(dataset_id, input=..., ...)` | Add a case and its first version | +| `update_item(item_id, base_version=..., input=..., expected_output=..., metadata=...)` | Update editable content with optimistic concurrency | +| `archive_item(item_id, base_version=...)` | Archive an active item with a new version | +| `restore_item(item_id, base_version=..., source_version=...)` | Restore an archived item, optionally copying a historical item version | +| `list_item_versions(item_id)` | Read item history, newest first | + +Dataset and item metadata are JSON objects. Inputs accept any non-null JSON value; expected/source outputs can be null. Writes require finite numbers, JSON string keys, and at most 32 nested containers. The server enforces dataset, item, version, and payload size limits; failures retain their codes and details in `EvaluationAPIError`. JSON values returned by reads are local copies. Editing them does not write to PostHog. + +To save source provenance on creation, supply `source_trace_id` together with a timezone-aware `source_timestamp`; optionally add `source_event_id`. Source fields and `client_item_id` cannot be edited later. + +### Updates and recovery + +```python +case = evaluations.datasets.get_item(item_id) +updated = evaluations.datasets.update_item( + case.id, + base_version=case.version, + expected_output=None, # Clear the answer; omitting it preserves it. + metadata={}, # Clear metadata; omitting it preserves it. +) +``` + +Pass the **observed item version number** as `base_version` for updates, archive, and restore. A stale version raises a 409 `stale_version` conflict with details in `error.response`, including `current_version`. The SDK does not fetch a newer version and overwrite it automatically. Changed content creates a version and dataset revision; identical content is a no-op. Dataset descriptions clear with `""`, metadata with `{}`, and tags with `[]`; those fields do not accept `None`. + +Reads retry within the configured transport limits. Item creates retry only when you supply a `client_item_id`. Other mutations never retry automatically. After an unknown write outcome, inspect the current state before issuing another mutation. Dataset errors use the same `EvaluationAPIError` as scorer and experiment operations, including `status`, `code`, `response`, and `persistence`. + +Run the supplied example against the provisioned dataset: + +```bash +uv run python examples/example-offline-evaluations/main.py \ + --dataset-id '' --state dataset-run.json + +# Optional: select an earlier numeric revision for a new run. +uv run python examples/example-offline-evaluations/main.py \ + --dataset-id '' --dataset-revision 1 --state historical-run.json +``` + +The example prepares and saves the pinned revision, execution identities, scorer version, and results **before the first experiment write**. If the state file already exists, replay uses that file without fetching a newer dataset, selecting another scorer version, or running the application again. Dataset selection arguments apply only when preparing a new state file. Choose a new file for a new run. This small example materializes its results; for larger workloads, use caller-sized batches and persist each prepared batch before upload. + +### Async datasets + +Await management methods and snapshot creation. Use `async for` on `iter_items()`; iteration itself is an async iterator, not an awaitable list. + +```python +from posthog.ai.evaluations import AsyncOfflineEvaluations, EvaluationItem + +async with AsyncOfflineEvaluations( + project_id=123, secret_key=personal_api_key, +) as evaluations: + snapshot = await evaluations.datasets.snapshot(dataset_id) + scorer = await evaluations.scorers.get(scorer_id) + experiment = await evaluations.create_experiment( + name="Async regression", dataset_revision_id=snapshot.revision_id, + ) + async for case in snapshot.iter_items(): + output = capital_answer(case.input) + item = EvaluationItem.from_dataset_item(case, output=output) + if case.expected_output is None: + await experiment.upload_result( + item=item, scorer_version_id=scorer.current_version_id, + status="not_applicable", + ) + else: + await experiment.upload_result( + item=item, scorer_version_id=scorer.current_version_id, + value=output == case.expected_output, + ) + await experiment.complete() +``` + +Install `posthog[async]` for async support. Cancellation propagates and does not automatically complete or fail an experiment. + ## Typed scorer configuration and polarity Configurations are public `TypedDict` types: editors suggest fields and type checkers connect `create(kind=...)` to the correct configuration. They are ordinary dictionaries at runtime; server validation remains authoritative. diff --git a/examples/example-offline-evaluations/main.py b/examples/example-offline-evaluations/main.py index a3c34171d..6c2e7826f 100644 --- a/examples/example-offline-evaluations/main.py +++ b/examples/example-offline-evaluations/main.py @@ -14,6 +14,7 @@ EvaluationAPIError, EvaluationItem, EvaluationResult, + JSONValue, OfflineEvaluations, ) @@ -33,8 +34,39 @@ def resolve_version(evaluations: OfflineEvaluations) -> str: return scorer.current_version_id +def capital_answer(input: JSONValue) -> str: + """A deterministic application to replace with your own model or agent.""" + if not isinstance(input, str): + raise ValueError("The capital-city example expects string dataset inputs.") + return {"Capital of France?": "Paris", "Capital of Italy?": "Milan"}.get( + input, "I don't know" + ) + + +def exact_match_result(item: EvaluationItem, version_id: str) -> EvaluationResult: + payload = item.to_dict()["payload"] + if payload.get("expected_output") is None: + return EvaluationResult( + item=item, + scorer_version_id=version_id, + status="not_applicable", + reasoning="This case has no expected answer.", + ) + return EvaluationResult( + item=item, + scorer_version_id=version_id, + value=payload["output"] == payload["expected_output"], + reasoning="Exact string comparison", + ) + + def prepare_state( - evaluations: OfflineEvaluations, project_id: int, host: str + evaluations: OfflineEvaluations, + project_id: int, + host: str, + *, + dataset_id: str | None = None, + dataset_revision: int | None = None, ) -> dict[str, Any]: version_id = resolve_version(evaluations) cases = [ @@ -51,24 +83,24 @@ def prepare_state( "expected": "Rome", }, ] - items = [ - EvaluationItem( - case_key=case["key"], - input=case["input"], - output=case["output"], - expected_output=case["expected"], - ) - for case in cases - ] - results = [ - EvaluationResult( - item=item, - scorer_version_id=version_id, - value=case["output"] == case["expected"], - reasoning="Exact string comparison", - ) - for item, case in zip(items, cases) - ] + snapshot = None + if dataset_id is not None: + snapshot = evaluations.datasets.snapshot(dataset_id, revision=dataset_revision) + items = [ + EvaluationItem.from_dataset_item(case, output=capital_answer(case.input)) + for case in snapshot.iter_items() + ] + else: + items = [ + EvaluationItem( + case_key=case["key"], + input=case["input"], + output=case["output"], + expected_output=case["expected"], + ) + for case in cases + ] + results = [exact_match_result(item, version_id) for item in items] return { "project_id": project_id, "host": host, @@ -79,6 +111,11 @@ def prepare_state( "run_source": "local", "expected_item_count": len(items), "expected_result_count": len(results), + **( + {"dataset_revision_id": snapshot.revision_id} + if snapshot is not None + else {} + ), }, "items": [item.to_dict() for item in items], "results": [result.to_dict() for result in results], @@ -108,7 +145,17 @@ def main() -> None: default=Path("offline-evaluation-state.json"), help="Create a new prepared run here, or replay the existing run exactly.", ) + parser.add_argument( + "--dataset-id", help="Run the capital-city application on a PostHog dataset." + ) + parser.add_argument( + "--dataset-revision", + type=int, + help="Pin this numeric revision; defaults to latest once.", + ) args = parser.parse_args() + if args.dataset_revision is not None and args.dataset_id is None: + parser.error("--dataset-revision requires --dataset-id") project_id = int(os.environ["POSTHOG_PROJECT_ID"]) host = os.environ.get("POSTHOG_HOST", "https://us.posthog.com") with OfflineEvaluations( @@ -133,7 +180,13 @@ def main() -> None: "The saved run belongs to a different project or host." ) else: - state = prepare_state(evaluations, project_id, host) + state = prepare_state( + evaluations, + project_id, + host, + dataset_id=args.dataset_id, + dataset_revision=args.dataset_revision, + ) save_state(args.state, state) items = {item["id"]: EvaluationItem.from_dict(item) for item in state["items"]} diff --git a/posthog/ai/evaluations/__init__.py b/posthog/ai/evaluations/__init__.py index 7d3e89b0d..2dbd0cc35 100644 --- a/posthog/ai/evaluations/__init__.py +++ b/posthog/ai/evaluations/__init__.py @@ -1,4 +1,4 @@ -"""Typed offline evaluation uploads, experiment lifecycle, and scorer management. +"""Typed offline evaluation uploads, experiments, scorers, and dataset management. from posthog.ai.evaluations import OfflineEvaluations, EvaluationItem @@ -10,6 +10,17 @@ # experiment.complete() """ +from ._async_datasets import AsyncDatasets, AsyncDatasetSnapshot +from ._dataset_types import ( + Dataset, + DatasetItem, + DatasetItemPage, + DatasetOrder, + DatasetPage, + DatasetRevision, + DatasetRevisionPage, +) +from ._datasets import Datasets, DatasetSnapshot from ._client import ( AsyncExperiment, AsyncOfflineEvaluations, @@ -51,6 +62,8 @@ ) __all__ = [ + "AsyncDatasets", + "AsyncDatasetSnapshot", "AsyncExperiment", "AsyncOfflineEvaluations", "AsyncScorers", @@ -60,6 +73,15 @@ "CategoricalPassingRule", "CategoricalScorerConfig", "CategoricalScorerOption", + "Dataset", + "DatasetItem", + "DatasetItemPage", + "DatasetOrder", + "DatasetPage", + "DatasetRevision", + "DatasetRevisionPage", + "Datasets", + "DatasetSnapshot", "EvaluationAPIError", "EvaluationItem", "EvaluationResult", diff --git a/posthog/ai/evaluations/_async_datasets.py b/posthog/ai/evaluations/_async_datasets.py new file mode 100644 index 000000000..80cc6418c --- /dev/null +++ b/posthog/ai/evaluations/_async_datasets.py @@ -0,0 +1,443 @@ +"""Asynchronous dataset management and revision-pinned iteration.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from datetime import datetime +from typing import AsyncIterator, Literal, Sequence +from uuid import UUID + +from ._dataset_serialization import ( + _body, + _create_item_body, + _dataset, + _item, + _item_list_params, + _list_params, + _page, + _page_params, + _parse, + _revision, +) +from ._dataset_types import ( + Dataset, + DatasetItem, + DatasetItemPage, + DatasetOrder, + DatasetPage, + DatasetRevisionPage, +) +from ._serialization import ( + JSONValue, + _UNSET, + _Unset, + _integer, + _uuid, +) +from ._transport import AsyncTransport + + +class AsyncDatasets: + """Manage datasets through ``AsyncOfflineEvaluations.datasets``. + + Requires a personal key with ``dataset:read`` or ``dataset:write`` and the + datasets feature enabled. Mutations return after acknowledgment; only item + creates with a caller-supplied ``client_item_id`` are automatically retried. + Other lost write responses require inspecting state before retrying. + """ + + def __init__(self, transport: AsyncTransport, project_id: int) -> None: + self._transport = transport + self._project_id = project_id + self._base = f"/api/projects/{project_id}/datasets/" + self._items = f"/api/projects/{project_id}/dataset_items/" + + async def create( + self, + *, + name: str, + description: str | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + tags: Sequence[str] | _Unset = _UNSET, + ) -> Dataset: + """Create an empty dataset. Names must be unique within the project. + + No revision exists until the first item is created. This operation is + not automatically retried, including after an ambiguous acknowledgment. + """ + return _parse( + lambda data: _dataset(data, self._project_id), + await self._transport.request( + "POST", + self._base, + body=_body( + dict( + name=name, description=description, metadata=metadata, tags=tags + ) + ), + retry_safe=False, + ), + ) + + async def get(self, dataset_id: str | UUID) -> Dataset: + """Fetch current metadata, including both current revision identifiers.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + await self._transport.request("GET", f"{self._base}{identity}/"), + ) + + async def list( + self, + *, + limit: int = 50, + offset: int = 0, + search: str | None = None, + archived: bool = False, + order_by: DatasetOrder = "-created_at", + tags: Sequence[str] | None = None, + tag_match: Literal["any", "all"] = "any", + ) -> DatasetPage: + """Fetch one page of active datasets, or archived datasets if requested. + + Search matches names, descriptions, and metadata. Keep filters and pass + ``next_offset`` to continue. Maximum limit is 100; tags accept 20 names. + """ + params = _list_params( + limit, offset, search, archived, order_by, tags, tag_match + ) + return _parse( + lambda data: DatasetPage( + *_page(data, lambda row: _dataset(row, self._project_id), offset) + ), + await self._transport.request("GET", self._base, params=params), + ) + + async def update( + self, + dataset_id: str | UUID, + *, + name: str | _Unset = _UNSET, + description: str | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + tags: Sequence[str] | _Unset = _UNSET, + ) -> Dataset: + """Replace supplied metadata fields; omitted fields remain unchanged. + + Use description="", metadata={}, or tags=[] to clear them. Metadata + updates do not create revisions. Use archive/restore for archive state. + """ + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + await self._transport.request( + "PATCH", + f"{self._base}{identity}/", + body=_body( + dict( + name=name, description=description, metadata=metadata, tags=tags + ) + ), + retry_safe=False, + ), + ) + + async def archive(self, dataset_id: str | UUID) -> Dataset: + """Archive a dataset. It stays readable but rejects item mutations.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + await self._transport.request( + "POST", f"{self._base}{identity}/archive/", body=b"{}", retry_safe=False + ), + ) + + async def restore(self, dataset_id: str | UUID) -> Dataset: + """Restore an archived dataset without changing individual item states.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + await self._transport.request( + "POST", f"{self._base}{identity}/restore/", body=b"{}", retry_safe=False + ), + ) + + async def list_revisions( + self, dataset_id: str | UUID, *, limit: int = 50, offset: int = 0 + ) -> DatasetRevisionPage: + """List immutable revisions newest first. Maximum page limit is 100.""" + identity = _uuid(dataset_id) + params = _page_params(limit, offset, 100) + return _parse( + lambda data: DatasetRevisionPage( + *_page( + data, lambda row: _revision(row, self._project_id, identity), offset + ) + ), + await self._transport.request( + "GET", f"{self._base}{identity}/revisions/", params=params + ), + ) + + async def list_items( + self, + dataset_id: str | UUID, + *, + revision: int | None = None, + archived: bool = False, + limit: int = 25, + offset: int = 0, + ) -> DatasetItemPage: + """Fetch one item page, optionally at an exact numeric dataset revision. + + Omitted revision reads current state for this request. Use ``snapshot`` + for consistent multi-page evaluation reads. Archived items are excluded + by default; archived=True selects only archived items. Maximum limit is 25. + """ + identity = _uuid(dataset_id) + params = _item_list_params(identity, revision, archived, limit, offset) + return _parse( + lambda data: DatasetItemPage( + *_page( + data, + lambda row: _item( + row, + self._project_id, + dataset_id=identity, + revision=revision, + archived=archived, + ), + offset, + ) + ), + await self._transport.request("GET", self._items, params=params), + ) + + async def get_item( + self, item_id: str | UUID, *, revision: int | None = None + ) -> DatasetItem: + """Fetch an item by stable UUID, optionally at a dataset revision number.""" + identity = _uuid(item_id) + params: dict[str, str | int] = ( + {} if revision is None else {"revision": _integer(revision)} + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, revision=revision), + await self._transport.request( + "GET", f"{self._items}{identity}/", params=params + ), + ) + + async def create_item( + self, + dataset_id: str | UUID, + *, + input: JSONValue, + expected_output: JSONValue | _Unset = _UNSET, + source_output: JSONValue | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + client_item_id: str | None = None, + source_trace_id: str | None = None, + source_event_id: str | None = None, + source_timestamp: datetime | str | None = None, + ) -> DatasetItem: + """Add a case, creating its first version and a dataset revision. + + ``input`` accepts any non-null JSON value. Supply a stable, case-sensitive + ``client_item_id`` to make identical creates retryable across processes. + A matching key with different current content or an archived item raises + a conflict. Source trace ID and timestamp must be supplied together; + source event ID additionally identifies an event within that trace. + """ + identity = _uuid(dataset_id) + body = _create_item_body( + identity, + input=input, + expected_output=expected_output, + source_output=source_output, + metadata=metadata, + client_item_id=client_item_id, + source_trace_id=source_trace_id, + source_event_id=source_event_id, + source_timestamp=source_timestamp, + ) + return _parse( + lambda data: _item( + data, self._project_id, dataset_id=identity, archived=False + ), + await self._transport.request( + "POST", self._items, body=body, retry_safe=client_item_id is not None + ), + ) + + async def update_item( + self, + item_id: str | UUID, + *, + base_version: int, + input: JSONValue | _Unset = _UNSET, + expected_output: JSONValue | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + ) -> DatasetItem: + """Update editable content using the observed item ``version``. + + Changed content creates a version and dataset revision; identical content + is a no-op. Omit fields to preserve them, use expected_output=None to clear + the answer, or metadata={} to clear metadata. Source fields are immutable. + Stale versions raise a conflict without automatic refresh or retry. + """ + identity = _uuid(item_id) + body = _body( + dict( + base_version=_integer(base_version), + input=input, + expected_output=expected_output, + metadata=metadata, + ) + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=False), + await self._transport.request( + "PATCH", f"{self._items}{identity}/", body=body, retry_safe=False + ), + ) + + async def archive_item( + self, item_id: str | UUID, *, base_version: int + ) -> DatasetItem: + """Archive an active item by creating a version; require its observed version.""" + identity = _uuid(item_id) + body = _body(dict(base_version=_integer(base_version))) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=True), + await self._transport.request( + "POST", f"{self._items}{identity}/archive/", body=body, retry_safe=False + ), + ) + + async def restore_item( + self, + item_id: str | UUID, + *, + base_version: int, + source_version: int | None = None, + ) -> DatasetItem: + """Restore an archived item, optionally copying a historical item version. + + ``base_version`` is the observed current version, even when copying an + older ``source_version``. Restoration creates a new immutable version. + """ + identity = _uuid(item_id) + body = _body( + dict( + base_version=_integer(base_version), + source_version=None + if source_version is None + else _integer(source_version), + ) + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=False), + await self._transport.request( + "POST", f"{self._items}{identity}/restore/", body=body, retry_safe=False + ), + ) + + async def list_item_versions( + self, item_id: str | UUID, *, limit: int = 25, offset: int = 0 + ) -> DatasetItemPage: + """List every item version, newest first. Maximum page limit is 100.""" + identity = _uuid(item_id) + params = _page_params(limit, offset, 100) + return _parse( + lambda data: DatasetItemPage( + *_page( + data, lambda row: _item(row, self._project_id, id=identity), offset + ) + ), + await self._transport.request( + "GET", f"{self._items}{identity}/versions/", params=params + ), + ) + + async def snapshot( + self, dataset_id: str | UUID, *, revision: int | None = None + ) -> AsyncDatasetSnapshot: + """Pin a revision now; item iteration subsequently fetches that exact revision. + + Omit revision to resolve latest once. Historical revisions are resolved + through paginated revision metadata. No items are fetched here. Raises + ValueError for a never-populated dataset or a nonexistent revision. + Keep the owning client open while iterating the returned snapshot. + """ + if revision is not None: + _integer(revision) + dataset = await self.get(dataset_id) + selected = dataset.current_revision if revision is None else revision + if selected is None: + raise ValueError( + "This dataset has no revision. Add an item before taking a snapshot." + ) + if dataset.current_revision is None or selected > dataset.current_revision: + raise ValueError(f"Dataset revision {selected} does not exist.") + if ( + selected == dataset.current_revision + and dataset.current_revision_id is not None + ): + return AsyncDatasetSnapshot( + dataset, selected, dataset.current_revision_id, self + ) + # Revisions are consecutive and newest first. Concurrent writes can + # shift their offsets, so verify the result and scan on a miss. + page = await self.list_revisions( + dataset.id, limit=1, offset=dataset.current_revision - selected + ) + for candidate in page.results: + if candidate.revision == selected: + return AsyncDatasetSnapshot(dataset, selected, candidate.id, self) + offset = 0 + while True: + page = await self.list_revisions(dataset.id, limit=100, offset=offset) + for candidate in page.results: + if candidate.revision == selected: + return AsyncDatasetSnapshot(dataset, selected, candidate.id, self) + if page.next_offset is None or ( + page.results and page.results[-1].revision < selected + ): + raise ValueError(f"Dataset revision {selected} does not exist.") + offset = page.next_offset + + +@dataclass(frozen=True) +class AsyncDatasetSnapshot: + """A revision-pinned read handle owned by an open AsyncOfflineEvaluations client. + + ``dataset`` is metadata observed when resolving the snapshot; descriptive + metadata is not historically versioned. Use ``revision_id`` when creating + an experiment, not the introducing revision on an individual DatasetItem. + Repeated iteration fetches the same active item versions without caching. + """ + + dataset: Dataset + revision: int + revision_id: str + _datasets: AsyncDatasets = field(repr=False, compare=False) + + async def iter_items(self, *, page_size: int = 25) -> AsyncIterator[DatasetItem]: + """Use async for to fetch active items at this revision, at most 25 per request. + + Each iteration starts at the first page. Memory is bounded by one page; + fetch failures propagate so callers cannot mistake a partial read for a + complete dataset. An existing revision with no active items yields none. + """ + _page_params(page_size, 0, 25) + offset = 0 + while True: + page = await self._datasets.list_items( + self.dataset.id, revision=self.revision, limit=page_size, offset=offset + ) + for item in page.results: + yield item + if page.next_offset is None: + return + offset = page.next_offset diff --git a/posthog/ai/evaluations/_client.py b/posthog/ai/evaluations/_client.py index 69fc622cb..db0a5d695 100644 --- a/posthog/ai/evaluations/_client.py +++ b/posthog/ai/evaluations/_client.py @@ -11,6 +11,8 @@ from typing_extensions import Unpack +from ._async_datasets import AsyncDatasets +from ._datasets import Datasets from ._errors import EvaluationAPIError from ._scorers import AsyncScorers, Scorers from ._serialization import ( @@ -402,11 +404,12 @@ async def fail(self) -> ExperimentReceipt: class OfflineEvaluations: - """Upload offline evaluations and manage scorers in one project/environment. + """Upload offline evaluations and manage scorers and datasets in one project. ``secret_key`` accepts personal or project secret keys with offline_evaluation_ingestion:write. Scorer reads/writes require a personal - key with llm_analytics:read/write. The offline feature must be enabled. + key with llm_analytics:read/write; datasets require dataset:read/write. + Each operation requires its corresponding product feature to be enabled. ``host`` defaults to the US app API; known ingestion hosts are mapped to their app hosts. Custom hosts are preserved. Requests use a 15 second timeout and at most three retries by default. Scorer creation/version bumps @@ -427,6 +430,7 @@ def __init__( ) self._project_id = project_id self.scorers = Scorers(self._transport, project_id) + self.datasets = Datasets(self._transport, project_id) self._path = f"/api/projects/{project_id}/ai_observability/offline_experiments/" def create_experiment( @@ -501,6 +505,7 @@ def __init__( ) self._project_id = project_id self.scorers = AsyncScorers(self._transport, project_id) + self.datasets = AsyncDatasets(self._transport, project_id) self._path = f"/api/projects/{project_id}/ai_observability/offline_experiments/" async def create_experiment( diff --git a/posthog/ai/evaluations/_dataset_serialization.py b/posthog/ai/evaluations/_dataset_serialization.py new file mode 100644 index 000000000..c95fb5aea --- /dev/null +++ b/posthog/ai/evaluations/_dataset_serialization.py @@ -0,0 +1,251 @@ +"""Dataset wire validation shared by the synchronous and asynchronous clients.""" + +from __future__ import annotations + +import json +from datetime import datetime +from typing import Any, Callable, Sequence, TypeVar, cast + +from ._dataset_types import Dataset, DatasetItem, DatasetOrder, DatasetRevision +from ._serialization import ( + JSONValue, + _Unset, + _boolean, + _date, + _encode, + _identifier, + _integer, + _next_offset, + _object, + _parse_response, + _text, + _timestamp, + _uuid, + _validate_json, +) +from ._tags import _response_tags, _tag_names, _tag_params + +_T = TypeVar("_T") + + +def _json(value: Any) -> JSONValue: + return cast(JSONValue, json.loads(_encode(value, sort_keys=False))) + + +def _metadata(value: Any) -> dict[str, JSONValue]: + return cast(dict[str, JSONValue], _json(_object(value))) + + +def _user(value: Any) -> dict[str, Any] | None: + return None if value is None else _metadata(value) + + +def _owner(data: dict[str, Any], project_id: int) -> int: + if _integer(data["team_id"]) != project_id: + raise ValueError("The dataset response belongs to another project.") + return project_id + + +def _dataset(data: dict[str, Any], project_id: int, id: str | None = None) -> Dataset: + identity = _uuid(data["id"]) + if id is not None and identity != id: + raise ValueError("Mismatched dataset ID.") + revision = data["current_revision"] + revision_id = data["current_revision_id"] + if (revision is None) != (revision_id is None): + raise ValueError("Incomplete dataset revision reference.") + return Dataset( + id=identity, + name=_text(data["name"]), + description=_text(data["description"]), + metadata=_metadata(data["metadata"]), + tags=_response_tags(data.get("tags", [])), + archived=_boolean(data["archived"]), + current_revision=None if revision is None else _integer(revision), + current_revision_id=None if revision_id is None else _uuid(revision_id), + created_at=_date(data["created_at"]), + updated_at=None if data["updated_at"] is None else _date(data["updated_at"]), + created_by=_user(data["created_by"]), + team_id=_owner(data, project_id), + ) + + +def _revision( + data: dict[str, Any], project_id: int, dataset_id: str +) -> DatasetRevision: + if _uuid(data["dataset_id"]) != dataset_id: + raise ValueError("Mismatched revision dataset ID.") + return DatasetRevision( + id=_uuid(data["id"]), + dataset_id=dataset_id, + revision=_integer(data["revision"]), + created_at=_date(data["created_at"]), + created_by=_user(data["created_by"]), + team_id=_owner(data, project_id), + ) + + +def _item( + data: dict[str, Any], + project_id: int, + *, + id: str | None = None, + dataset_id: str | None = None, + revision: int | None = None, + archived: bool | None = None, +) -> DatasetItem: + identity, owner = _uuid(data["id"]), _uuid(data["dataset"]) + introduced = _integer(data["dataset_revision"]) + is_archived = _boolean(data["archived"]) + if (id is not None and identity != id) or ( + dataset_id is not None and owner != dataset_id + ): + raise ValueError("Mismatched dataset item identity.") + if revision is not None and introduced > revision: + raise ValueError("The item version is newer than the requested revision.") + if archived is not None and is_archived != archived: + raise ValueError("The item does not match the requested archive filter.") + if data["input"] is None: + raise ValueError("Dataset inputs cannot be null.") + return DatasetItem( + id=identity, + dataset_id=owner, + client_item_id=_identifier(data["client_item_id"], "client_item_id"), + version=_integer(data["version"]), + version_id=_uuid(data["version_id"]), + dataset_revision=introduced, + dataset_revision_id=_uuid(data["dataset_revision_id"]), + archived=is_archived, + input=_json(data["input"]), + expected_output=_json(data["expected_output"]), + source_output=_json(data["source_output"]), + metadata=_metadata(data["metadata"]), + source_trace_id=_identifier(data["source_trace_id"], "source_trace_id"), + source_event_id=_identifier(data["source_event_id"], "source_event_id"), + source_timestamp=None + if data["source_timestamp"] is None + else _date(data["source_timestamp"]), + created_at=_date(data["created_at"]), + updated_at=None if data["updated_at"] is None else _date(data["updated_at"]), + created_by=_user(data["created_by"]), + version_created_at=_date(data["version_created_at"]), + version_created_by=_user(data["version_created_by"]), + team_id=_owner(data, project_id), + ) + + +def _parse(parser: Callable[[dict[str, Any]], _T], data: dict[str, Any]) -> _T: + return _parse_response( + parser, data, detail="The dataset API returned an invalid response." + ) + + +def _page( + data: dict[str, Any], parser: Callable[[dict[str, Any]], _T], offset: int +) -> tuple[int, tuple[_T, ...], int | None]: + rows = data["results"] + if not isinstance(rows, list): + raise ValueError("Expected a list of dataset results.") + results = tuple(parser(_object(row)) for row in rows) + count = _integer(data["count"], minimum=0) + next_offset = _next_offset(data["next"], minimum=offset + 1) + if next_offset is not None and not results: + raise ValueError("An empty page must not have a continuation.") + return count, results, next_offset + + +def _page_params(limit: int, offset: int, maximum: int) -> dict[str, str | int]: + if _integer(limit) > maximum: + raise ValueError(f"Page limit must be between 1 and {maximum}.") + return {"limit": limit, "offset": _integer(offset, minimum=0)} + + +def _list_params( + limit: int, + offset: int, + search: str | None, + archived: bool, + order_by: DatasetOrder, + tags: Sequence[str] | None, + tag_match: str, +) -> dict[str, str | int]: + params = _page_params(limit, offset, 100) + params.update(_tag_params(tags, tag_match)) + params["archived"] = "true" if _boolean(archived) else "false" + if order_by not in ("created_at", "-created_at", "updated_at", "-updated_at"): + raise ValueError("Unsupported dataset order.") + params["order_by"] = order_by + if search is not None: + if not isinstance(search, str) or not search.strip(): + raise ValueError("search must be a nonempty string.") + params["search"] = search + return params + + +def _item_list_params( + dataset_id: str, revision: int | None, archived: bool, limit: int, offset: int +) -> dict[str, str | int]: + params = _page_params(limit, offset, 25) + params["dataset"] = dataset_id + params["archived"] = "true" if _boolean(archived) else "false" + if revision is not None: + params["revision"] = _integer(revision) + return params + + +def _body(fields: dict[str, Any]) -> bytes: + data = { + key: value for key, value in fields.items() if not isinstance(value, _Unset) + } + for key in ("name", "description"): + if key in data: + value = _text(data[key]) + maximum = 400 if key == "name" else 10_000 + if len(value) > maximum or (key == "name" and not value.strip()): + raise ValueError(f"Invalid dataset {key}.") + if "input" in data and data["input"] is None: + raise ValueError("Dataset inputs cannot be null.") + if "metadata" in data: + _object(data["metadata"]) + if "tags" in data: + data["tags"] = _tag_names(data["tags"]) + _validate_json(data) + return _encode(data) + + +def _create_item_body( + dataset_id: str, + *, + input: JSONValue, + expected_output: JSONValue | _Unset, + source_output: JSONValue | _Unset, + metadata: dict[str, JSONValue] | _Unset, + client_item_id: str | None, + source_trace_id: str | None, + source_event_id: str | None, + source_timestamp: datetime | str | None, +) -> bytes: + client_item_id = _identifier(client_item_id, "client_item_id") + source_trace_id = _identifier(source_trace_id, "source_trace_id") + source_event_id = _identifier(source_event_id, "source_event_id") + if (source_trace_id is None) != (source_timestamp is None) or ( + source_trace_id is None and source_event_id is not None + ): + raise ValueError( + "Source provenance requires both source_trace_id and source_timestamp." + ) + return _body( + dict( + dataset=dataset_id, + input=input, + expected_output=expected_output, + source_output=source_output, + metadata=metadata, + client_item_id=client_item_id, + source_trace_id=source_trace_id, + source_event_id=source_event_id, + source_timestamp=None + if source_timestamp is None + else _timestamp(source_timestamp), + ) + ) diff --git a/posthog/ai/evaluations/_dataset_types.py b/posthog/ai/evaluations/_dataset_types.py new file mode 100644 index 000000000..5f51ca253 --- /dev/null +++ b/posthog/ai/evaluations/_dataset_types.py @@ -0,0 +1,111 @@ +"""Typed dataset metadata, immutable version references, and paginated reads.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from datetime import datetime +from typing import Any, Literal + +from ._serialization import JSONValue + +DatasetOrder = Literal["created_at", "-created_at", "updated_at", "-updated_at"] + + +@dataclass(frozen=True) +class Dataset: + """A dataset's current metadata, separate from its immutable item revisions. + + Names are unique within a project. Use ``id`` for subsequent operations. + Both revision fields are None until the first item is created. Metadata + dictionaries are local copies, not live server state. + """ + + id: str + name: str + description: str + metadata: dict[str, JSONValue] = field(repr=False) + tags: tuple[str, ...] + archived: bool + current_revision: int | None + current_revision_id: str | None + created_at: datetime + updated_at: datetime | None + created_by: dict[str, Any] | None + team_id: int + + +@dataclass(frozen=True) +class DatasetRevision: + """An immutable dataset revision. Reads use ``revision``; experiments use ``id``.""" + + id: str + dataset_id: str + revision: int + created_at: datetime + created_by: dict[str, Any] | None + team_id: int + + +@dataclass(frozen=True) +class DatasetItem: + """One version of a dataset case, with stable ``id`` and immutable ``version_id``. + + ``dataset_revision`` and ``dataset_revision_id`` identify the revision that + introduced this version, which may precede the snapshot being read. Use + the snapshot's revision ID when creating an experiment. ``source_output`` + is the original trace's output, not a new execution or expected answer. + JSON values are local copies; changing them does not update the dataset. + """ + + id: str + dataset_id: str + client_item_id: str | None + version: int + version_id: str + dataset_revision: int + dataset_revision_id: str + archived: bool + input: JSONValue = field(repr=False) + expected_output: JSONValue = field(repr=False) + source_output: JSONValue = field(repr=False) + metadata: dict[str, JSONValue] = field(repr=False) + source_trace_id: str | None + source_event_id: str | None + source_timestamp: datetime | None + created_at: datetime + updated_at: datetime | None + created_by: dict[str, Any] | None + version_created_at: datetime + version_created_by: dict[str, Any] | None + team_id: int + + +@dataclass(frozen=True) +class DatasetPage: + """One dataset page. Keep filters and pass ``next_offset`` to continue.""" + + count: int + results: tuple[Dataset, ...] + next_offset: int | None + + +@dataclass(frozen=True) +class DatasetRevisionPage: + """One page of revisions, newest first. None ``next_offset`` ends the list.""" + + count: int + results: tuple[DatasetRevision, ...] + next_offset: int | None + + +@dataclass(frozen=True) +class DatasetItemPage: + """One page of items or item history. None ``next_offset`` ends the list. + + Keep the dataset, revision, and archive filter unchanged when continuing + an item listing. For a complete pinned read, prefer ``snapshot.iter_items``. + """ + + count: int + results: tuple[DatasetItem, ...] + next_offset: int | None diff --git a/posthog/ai/evaluations/_datasets.py b/posthog/ai/evaluations/_datasets.py new file mode 100644 index 000000000..cfe359a2e --- /dev/null +++ b/posthog/ai/evaluations/_datasets.py @@ -0,0 +1,436 @@ +"""Dataset management and revision-pinned iteration.""" + +from __future__ import annotations + +from dataclasses import dataclass, field +from datetime import datetime +from typing import Iterator, Literal, Sequence +from uuid import UUID + +from ._dataset_serialization import ( + _body, + _create_item_body, + _dataset, + _item, + _item_list_params, + _list_params, + _page, + _page_params, + _parse, + _revision, +) +from ._dataset_types import ( + Dataset, + DatasetItem, + DatasetItemPage, + DatasetOrder, + DatasetPage, + DatasetRevisionPage, +) +from ._serialization import ( + JSONValue, + _UNSET, + _Unset, + _integer, + _uuid, +) +from ._transport import SyncTransport + + +class Datasets: + """Manage datasets through ``OfflineEvaluations.datasets``. + + Requires a personal key with ``dataset:read`` or ``dataset:write`` and the + datasets feature enabled. Mutations return after acknowledgment; only item + creates with a caller-supplied ``client_item_id`` are automatically retried. + Other lost write responses require inspecting state before retrying. + """ + + def __init__(self, transport: SyncTransport, project_id: int) -> None: + self._transport = transport + self._project_id = project_id + self._base = f"/api/projects/{project_id}/datasets/" + self._items = f"/api/projects/{project_id}/dataset_items/" + + def create( + self, + *, + name: str, + description: str | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + tags: Sequence[str] | _Unset = _UNSET, + ) -> Dataset: + """Create an empty dataset. Names must be unique within the project. + + No revision exists until the first item is created. This operation is + not automatically retried, including after an ambiguous acknowledgment. + """ + return _parse( + lambda data: _dataset(data, self._project_id), + self._transport.request( + "POST", + self._base, + body=_body( + dict( + name=name, description=description, metadata=metadata, tags=tags + ) + ), + retry_safe=False, + ), + ) + + def get(self, dataset_id: str | UUID) -> Dataset: + """Fetch current metadata, including both current revision identifiers.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + self._transport.request("GET", f"{self._base}{identity}/"), + ) + + def list( + self, + *, + limit: int = 50, + offset: int = 0, + search: str | None = None, + archived: bool = False, + order_by: DatasetOrder = "-created_at", + tags: Sequence[str] | None = None, + tag_match: Literal["any", "all"] = "any", + ) -> DatasetPage: + """Fetch one page of active datasets, or archived datasets if requested. + + Search matches names, descriptions, and metadata. Keep filters and pass + ``next_offset`` to continue. Maximum limit is 100; tags accept 20 names. + """ + params = _list_params( + limit, offset, search, archived, order_by, tags, tag_match + ) + return _parse( + lambda data: DatasetPage( + *_page(data, lambda row: _dataset(row, self._project_id), offset) + ), + self._transport.request("GET", self._base, params=params), + ) + + def update( + self, + dataset_id: str | UUID, + *, + name: str | _Unset = _UNSET, + description: str | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + tags: Sequence[str] | _Unset = _UNSET, + ) -> Dataset: + """Replace supplied metadata fields; omitted fields remain unchanged. + + Use description="", metadata={}, or tags=[] to clear them. Metadata + updates do not create revisions. Use archive/restore for archive state. + """ + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + self._transport.request( + "PATCH", + f"{self._base}{identity}/", + body=_body( + dict( + name=name, description=description, metadata=metadata, tags=tags + ) + ), + retry_safe=False, + ), + ) + + def archive(self, dataset_id: str | UUID) -> Dataset: + """Archive a dataset. It stays readable but rejects item mutations.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + self._transport.request( + "POST", f"{self._base}{identity}/archive/", body=b"{}", retry_safe=False + ), + ) + + def restore(self, dataset_id: str | UUID) -> Dataset: + """Restore an archived dataset without changing individual item states.""" + identity = _uuid(dataset_id) + return _parse( + lambda data: _dataset(data, self._project_id, identity), + self._transport.request( + "POST", f"{self._base}{identity}/restore/", body=b"{}", retry_safe=False + ), + ) + + def list_revisions( + self, dataset_id: str | UUID, *, limit: int = 50, offset: int = 0 + ) -> DatasetRevisionPage: + """List immutable revisions newest first. Maximum page limit is 100.""" + identity = _uuid(dataset_id) + params = _page_params(limit, offset, 100) + return _parse( + lambda data: DatasetRevisionPage( + *_page( + data, lambda row: _revision(row, self._project_id, identity), offset + ) + ), + self._transport.request( + "GET", f"{self._base}{identity}/revisions/", params=params + ), + ) + + def list_items( + self, + dataset_id: str | UUID, + *, + revision: int | None = None, + archived: bool = False, + limit: int = 25, + offset: int = 0, + ) -> DatasetItemPage: + """Fetch one item page, optionally at an exact numeric dataset revision. + + Omitted revision reads current state for this request. Use ``snapshot`` + for consistent multi-page evaluation reads. Archived items are excluded + by default; archived=True selects only archived items. Maximum limit is 25. + """ + identity = _uuid(dataset_id) + params = _item_list_params(identity, revision, archived, limit, offset) + return _parse( + lambda data: DatasetItemPage( + *_page( + data, + lambda row: _item( + row, + self._project_id, + dataset_id=identity, + revision=revision, + archived=archived, + ), + offset, + ) + ), + self._transport.request("GET", self._items, params=params), + ) + + def get_item( + self, item_id: str | UUID, *, revision: int | None = None + ) -> DatasetItem: + """Fetch an item by stable UUID, optionally at a dataset revision number.""" + identity = _uuid(item_id) + params: dict[str, str | int] = ( + {} if revision is None else {"revision": _integer(revision)} + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, revision=revision), + self._transport.request("GET", f"{self._items}{identity}/", params=params), + ) + + def create_item( + self, + dataset_id: str | UUID, + *, + input: JSONValue, + expected_output: JSONValue | _Unset = _UNSET, + source_output: JSONValue | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + client_item_id: str | None = None, + source_trace_id: str | None = None, + source_event_id: str | None = None, + source_timestamp: datetime | str | None = None, + ) -> DatasetItem: + """Add a case, creating its first version and a dataset revision. + + ``input`` accepts any non-null JSON value. Supply a stable, case-sensitive + ``client_item_id`` to make identical creates retryable across processes. + A matching key with different current content or an archived item raises + a conflict. Source trace ID and timestamp must be supplied together; + source event ID additionally identifies an event within that trace. + """ + identity = _uuid(dataset_id) + body = _create_item_body( + identity, + input=input, + expected_output=expected_output, + source_output=source_output, + metadata=metadata, + client_item_id=client_item_id, + source_trace_id=source_trace_id, + source_event_id=source_event_id, + source_timestamp=source_timestamp, + ) + return _parse( + lambda data: _item( + data, self._project_id, dataset_id=identity, archived=False + ), + self._transport.request( + "POST", self._items, body=body, retry_safe=client_item_id is not None + ), + ) + + def update_item( + self, + item_id: str | UUID, + *, + base_version: int, + input: JSONValue | _Unset = _UNSET, + expected_output: JSONValue | _Unset = _UNSET, + metadata: dict[str, JSONValue] | _Unset = _UNSET, + ) -> DatasetItem: + """Update editable content using the observed item ``version``. + + Changed content creates a version and dataset revision; identical content + is a no-op. Omit fields to preserve them, use expected_output=None to clear + the answer, or metadata={} to clear metadata. Source fields are immutable. + Stale versions raise a conflict without automatic refresh or retry. + """ + identity = _uuid(item_id) + body = _body( + dict( + base_version=_integer(base_version), + input=input, + expected_output=expected_output, + metadata=metadata, + ) + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=False), + self._transport.request( + "PATCH", f"{self._items}{identity}/", body=body, retry_safe=False + ), + ) + + def archive_item(self, item_id: str | UUID, *, base_version: int) -> DatasetItem: + """Archive an active item by creating a version; require its observed version.""" + identity = _uuid(item_id) + body = _body(dict(base_version=_integer(base_version))) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=True), + self._transport.request( + "POST", f"{self._items}{identity}/archive/", body=body, retry_safe=False + ), + ) + + def restore_item( + self, + item_id: str | UUID, + *, + base_version: int, + source_version: int | None = None, + ) -> DatasetItem: + """Restore an archived item, optionally copying a historical item version. + + ``base_version`` is the observed current version, even when copying an + older ``source_version``. Restoration creates a new immutable version. + """ + identity = _uuid(item_id) + body = _body( + dict( + base_version=_integer(base_version), + source_version=None + if source_version is None + else _integer(source_version), + ) + ) + return _parse( + lambda data: _item(data, self._project_id, id=identity, archived=False), + self._transport.request( + "POST", f"{self._items}{identity}/restore/", body=body, retry_safe=False + ), + ) + + def list_item_versions( + self, item_id: str | UUID, *, limit: int = 25, offset: int = 0 + ) -> DatasetItemPage: + """List every item version, newest first. Maximum page limit is 100.""" + identity = _uuid(item_id) + params = _page_params(limit, offset, 100) + return _parse( + lambda data: DatasetItemPage( + *_page( + data, lambda row: _item(row, self._project_id, id=identity), offset + ) + ), + self._transport.request( + "GET", f"{self._items}{identity}/versions/", params=params + ), + ) + + def snapshot( + self, dataset_id: str | UUID, *, revision: int | None = None + ) -> DatasetSnapshot: + """Pin a revision now; item iteration subsequently fetches that exact revision. + + Omit revision to resolve latest once. Historical revisions are resolved + through paginated revision metadata. No items are fetched here. Raises + ValueError for a never-populated dataset or a nonexistent revision. + Keep the owning client open while iterating the returned snapshot. + """ + if revision is not None: + _integer(revision) + dataset = self.get(dataset_id) + selected = dataset.current_revision if revision is None else revision + if selected is None: + raise ValueError( + "This dataset has no revision. Add an item before taking a snapshot." + ) + if dataset.current_revision is None or selected > dataset.current_revision: + raise ValueError(f"Dataset revision {selected} does not exist.") + if ( + selected == dataset.current_revision + and dataset.current_revision_id is not None + ): + return DatasetSnapshot(dataset, selected, dataset.current_revision_id, self) + # Revisions are consecutive and newest first. Concurrent writes can + # shift their offsets, so verify the result and scan on a miss. + page = self.list_revisions( + dataset.id, limit=1, offset=dataset.current_revision - selected + ) + for candidate in page.results: + if candidate.revision == selected: + return DatasetSnapshot(dataset, selected, candidate.id, self) + offset = 0 + while True: + page = self.list_revisions(dataset.id, limit=100, offset=offset) + for candidate in page.results: + if candidate.revision == selected: + return DatasetSnapshot(dataset, selected, candidate.id, self) + if page.next_offset is None or ( + page.results and page.results[-1].revision < selected + ): + raise ValueError(f"Dataset revision {selected} does not exist.") + offset = page.next_offset + + +@dataclass(frozen=True) +class DatasetSnapshot: + """A revision-pinned read handle owned by an open OfflineEvaluations client. + + ``dataset`` is metadata observed when resolving the snapshot; descriptive + metadata is not historically versioned. Use ``revision_id`` when creating + an experiment, not the introducing revision on an individual DatasetItem. + Repeated iteration fetches the same active item versions without caching. + """ + + dataset: Dataset + revision: int + revision_id: str + _datasets: Datasets = field(repr=False, compare=False) + + def iter_items(self, *, page_size: int = 25) -> Iterator[DatasetItem]: + """Lazily fetch active items at this revision, at most 25 per request. + + Each iteration starts at the first page. Memory is bounded by one page; + fetch failures propagate so callers cannot mistake a partial read for a + complete dataset. An existing revision with no active items yields none. + """ + _page_params(page_size, 0, 25) + offset = 0 + while True: + page = self._datasets.list_items( + self.dataset.id, revision=self.revision, limit=page_size, offset=offset + ) + yield from page.results + if page.next_offset is None: + return + offset = page.next_offset diff --git a/posthog/ai/evaluations/_scorers.py b/posthog/ai/evaluations/_scorers.py index 1d9e15483..a99bd7ddf 100644 --- a/posthog/ai/evaluations/_scorers.py +++ b/posthog/ai/evaluations/_scorers.py @@ -6,10 +6,8 @@ import json from datetime import datetime from typing import Any, Callable, Literal, Sequence, TypeVar, cast, overload -from urllib.parse import parse_qs, urlsplit from uuid import UUID -from ._errors import EvaluationAPIError from ._scorer_types import ( BooleanScorerConfig, CategoricalScorerConfig, @@ -22,7 +20,8 @@ ScorerVersion, ScorerVersionPage, ) -from ._tags import _response_tags, _tag_names +from ._serialization import _integer, _next_offset, _parse_response, _text +from ._tags import _response_tags, _tag_names, _tag_params from ._transport import AsyncTransport, SyncTransport @@ -47,18 +46,6 @@ def _uuid(value: str | UUID) -> str: raise ValueError("Scorer and version IDs must be UUIDs.") from None -def _integer(value: Any, *, minimum: int = 0) -> int: - if type(value) is not int or value < minimum: - raise ValueError("Expected an integer within the supported range.") - return value - - -def _text(value: Any) -> str: - if not isinstance(value, str): - raise ValueError("Expected a string.") - return value - - def _optional_text(value: Any) -> str | None: return None if value is None else _text(value) @@ -129,24 +116,18 @@ def _results(data: dict[str, Any]) -> list[dict[str, Any]]: def _scorer_page(data: dict[str, Any]) -> ScorerPage: next_url = _optional_text(data["next"]) - next_offset = None - if next_url is not None: - offsets = parse_qs(urlsplit(next_url).query).get("offset") - if offsets is None or len(offsets) != 1: - raise ValueError("Missing scorer page offset.") - next_offset = _integer(int(offsets[0])) return ScorerPage( - count=_integer(data["count"]), + count=_integer(data["count"], minimum=0), results=tuple(_scorer(row) for row in _results(data)), next=next_url, previous=_optional_text(data["previous"]), - next_offset=next_offset, + next_offset=_next_offset(next_url), ) def _version_page(data: dict[str, Any]) -> ScorerVersionPage: return ScorerVersionPage( - count=_integer(data["count"]), + count=_integer(data["count"], minimum=0), results=tuple(_version(row) for row in _results(data)), next_cursor=_optional_text(data["next_cursor"]), ) @@ -155,15 +136,9 @@ def _version_page(data: dict[str, Any]) -> ScorerVersionPage: def _parse( parser: Callable[[dict[str, Any]], _ResultT], data: dict[str, Any] ) -> _ResultT: - try: - return parser(data) - except (KeyError, TypeError, ValueError, OverflowError): - raise EvaluationAPIError( - code="invalid_response", - detail="The scorer API returned an invalid response.", - response=data, - persistence="unknown", - ) from None + return _parse_response( + parser, data, detail="The scorer API returned an invalid response." + ) def _encode(data: dict[str, Any]) -> bytes: @@ -235,11 +210,10 @@ def _list_params( tags: Sequence[str] | None, tag_match: Literal["any", "all"], ) -> dict[str, str | int]: - if tag_match not in ("any", "all"): - raise ValueError("tag_match must be any or all.") + tag_params = _tag_params(tags, tag_match) params: dict[str, str | int] = { "limit": _integer(limit, minimum=1), - "offset": _integer(offset), + "offset": _integer(offset, minimum=0), } if search is not None: params["search"] = search @@ -251,11 +225,7 @@ def _list_params( params["archived"] = "true" if archived else "false" if order_by is not None: params["order_by"] = order_by - if tags is not None: - params["tags"] = json.dumps(_tag_names(tags, limit=20), ensure_ascii=False) - params["tag_match"] = tag_match - elif tag_match != "any": - params["tag_match"] = tag_match + params.update(tag_params) return params diff --git a/posthog/ai/evaluations/_serialization.py b/posthog/ai/evaluations/_serialization.py index b0d8bf448..83aadb280 100644 --- a/posthog/ai/evaluations/_serialization.py +++ b/posthog/ai/evaluations/_serialization.py @@ -3,9 +3,12 @@ import json import math from datetime import datetime, timezone -from typing import Any, Iterable, Union, cast +from typing import Any, Callable, Iterable, TypeVar, Union, cast +from urllib.parse import parse_qs, urlsplit from uuid import UUID +from ._errors import EvaluationAPIError + JSONValue = Union[ None, bool, int, float, str, list["JSONValue"], dict[str, "JSONValue"] ] @@ -22,6 +25,46 @@ def __repr__(self) -> str: _MAX_REQUEST_BYTES = 5 * 1024 * 1024 _MAX_ITEM_BYTES = 1024 * 1024 _MAX_RESULT_BYTES = 256 * 1024 +_ResponseT = TypeVar("_ResponseT") + + +def _parse_response( + parser: Callable[[dict[str, Any]], _ResponseT], + data: dict[str, Any], + *, + detail: str, +) -> _ResponseT: + try: + return parser(data) + except (KeyError, TypeError, ValueError, OverflowError): + raise EvaluationAPIError( + code="invalid_response", + detail=detail, + response=data, + persistence="unknown", + ) from None + + +def _integer(value: Any, *, minimum: int = 1) -> int: + if type(value) is not int or value < minimum: + raise ValueError(f"Expected an integer greater than or equal to {minimum}.") + return value + + +def _text(value: Any) -> str: + if not isinstance(value, str): + raise ValueError("Expected a string.") + return value + + +def _next_offset(value: Any, *, minimum: int = 0) -> int | None: + if value is None: + return None + # Extract only the continuation. Never send credentials to a response URL. + offsets = parse_qs(urlsplit(_text(value)).query).get("offset") + if offsets is None or len(offsets) != 1: + raise ValueError("Missing page offset.") + return _integer(int(offsets[0]), minimum=minimum) def _uuid(value: object) -> str: @@ -51,14 +94,14 @@ def _identifier(value: object, field: str, limit: int = 255) -> str | None: return value -def _encode(value: object) -> bytes: +def _encode(value: object, *, sort_keys: bool = True) -> bytes: try: return json.dumps( value, ensure_ascii=False, allow_nan=False, separators=(",", ":"), - sort_keys=True, + sort_keys=sort_keys, ).encode("utf-8") except (TypeError, ValueError, UnicodeError) as exc: raise ValueError( diff --git a/posthog/ai/evaluations/_tags.py b/posthog/ai/evaluations/_tags.py index be1448f70..b78f0ca17 100644 --- a/posthog/ai/evaluations/_tags.py +++ b/posthog/ai/evaluations/_tags.py @@ -1,7 +1,8 @@ -"""Shared validation for mutable scorer and experiment tags.""" +"""Shared validation and filters for scorer, dataset, and experiment tags.""" from __future__ import annotations +import json from collections.abc import Sequence from typing import Any @@ -26,3 +27,14 @@ def _response_tags(value: Any) -> tuple[str, ...]: if not isinstance(value, list) or any(not isinstance(tag, str) for tag in value): raise ValueError("Expected a list of tag names.") return tuple(value) + + +def _tag_params(tags: Sequence[str] | None, tag_match: str) -> dict[str, str | int]: + if tag_match not in ("any", "all"): + raise ValueError("tag_match must be any or all.") + params: dict[str, str | int] = {} + if tags is not None: + params["tags"] = json.dumps(_tag_names(tags, limit=20), ensure_ascii=False) + if tags is not None or tag_match != "any": + params["tag_match"] = tag_match + return params diff --git a/posthog/ai/evaluations/_types.py b/posthog/ai/evaluations/_types.py index c6862b37d..7992ac1c9 100644 --- a/posthog/ai/evaluations/_types.py +++ b/posthog/ai/evaluations/_types.py @@ -8,6 +8,7 @@ from typing_extensions import TypedDict +from ._dataset_types import DatasetItem from ._errors import EvaluationAPIError from ._serialization import ( JSONValue, @@ -135,6 +136,45 @@ def to_dict(self) -> dict[str, Any]: """Return a defensive, JSON-serializable copy of the complete declaration.""" return json.loads(self._json) + @classmethod + def from_dataset_item( + cls, + item: DatasetItem, + *, + output: JSONValue | _Unset = _UNSET, + id: str | UUID | None = None, + case_key: str | None = None, + trial: str | None = None, + application_trace_id: str | None = None, + ) -> EvaluationItem: + """Declare one execution of a dataset case, preserving its exact version. + + Copies input, expected output, and metadata; supply the new execution's + output and trace ID. Source output/provenance are never substituted. + A fresh execution UUID is generated unless id is supplied. Reuse the + returned item across scorers; call again for each independent trial. + ``case_key`` defaults to the caller-owned client item ID, or stable item + UUID. Omit output for an execution that failed before producing one. + Use the owning snapshot's revision_id when creating the experiment. + """ + if not isinstance(item, DatasetItem): + raise TypeError("Expected a DatasetItem.") + if item.archived: + raise ValueError("Archived dataset items cannot be evaluated.") + return cls( + id=id, + input=item.input, + output=output, + expected_output=item.expected_output, + metadata=item.metadata, + case_key=(item.client_item_id or item.id) if case_key is None else case_key, + trial=trial, + dataset_item_identifier=item.id, + dataset_item_version_identifier=item.version_id, + dataset_item_version_id=item.version_id, + application_trace_id=application_trace_id, + ) + @classmethod def from_dict(cls, data: Mapping[str, Any]) -> EvaluationItem: """Restore a saved declaration, including its required original UUID.""" diff --git a/posthog/test/ai/test_evaluations_datasets.py b/posthog/test/ai/test_evaluations_datasets.py new file mode 100644 index 000000000..e90d34005 --- /dev/null +++ b/posthog/test/ai/test_evaluations_datasets.py @@ -0,0 +1,838 @@ +import asyncio +import copy +import importlib.util +import inspect +import json +from dataclasses import FrozenInstanceError, replace +from datetime import datetime, timezone +from pathlib import Path +from unittest.mock import AsyncMock, Mock, patch +from uuid import UUID + +import httpx +import pytest +import requests + +from posthog.ai.evaluations import ( + AsyncOfflineEvaluations, + DatasetItemPage, + EvaluationAPIError, + EvaluationItem, + EvaluationResult, + OfflineEvaluations, +) +from posthog.ai.evaluations import _client +from posthog.ai.evaluations._transport import AsyncTransport, SyncTransport + +from .test_evaluations import respond as respond_to_experiment +from .test_evaluations_scorers import scorer_response + +DATASET_ID = "015e4ac4-3659-456b-998c-4345b4e4c846" +ITEM_ID = "7d1e9d28-9b64-4c95-b4ad-3e6fa6b975b1" +OTHER_ITEM_ID = "b492bf6b-bb45-4374-aefb-e40a8eecfc62" +VERSION_ID = "9e2bdd1a-ad9e-4a96-9bc0-77a7f4d8b35e" +REVISION_ID = "ba71a1bb-836f-4c19-9d06-1d36d44948a4" +OLD_REVISION_ID = "a4137aa9-4e27-4829-928b-568cc55a0082" +TIMESTAMP = "2026-10-20T10:00:00Z" +BASE = "/api/projects/123/datasets/" +ITEMS = "/api/projects/123/dataset_items/" + + +def dataset_response(**overrides): + return { + "id": DATASET_ID, + "name": "Capital cities", + "description": "Regression cases", + "metadata": {"owner": "support"}, + "tags": ["regression"], + "archived": False, + "current_revision": 3, + "current_revision_id": REVISION_ID, + "created_at": TIMESTAMP, + "updated_at": None, + "created_by": None, + "team_id": 123, + **overrides, + } + + +def revision_response(**overrides): + return { + "id": OLD_REVISION_ID, + "dataset_id": DATASET_ID, + "revision": 1, + "created_at": TIMESTAMP, + "created_by": None, + "team_id": 123, + **overrides, + } + + +def item_response(**overrides): + return { + "id": ITEM_ID, + "dataset": DATASET_ID, + "client_item_id": "capital-france", + "version": 2, + "version_id": VERSION_ID, + "dataset_revision": 2, + "dataset_revision_id": OLD_REVISION_ID, + "archived": False, + "input": {"question": "Capital of France?"}, + "expected_output": "Paris", + "source_output": "Lyon", + "metadata": {"category": ["geography"]}, + "source_trace_id": "source-trace", + "source_event_id": "source-event", + "source_timestamp": TIMESTAMP, + "created_at": TIMESTAMP, + "updated_at": TIMESTAMP, + "created_by": None, + "version_created_at": TIMESTAMP, + "version_created_by": None, + "team_id": 123, + **overrides, + } + + +def page_response(*rows, next_offset=None, count=None): + return { + "count": len(rows) if count is None else count, + "results": list(rows), + "next": None + if next_offset is None + else f"https://us.posthog.com{ITEMS}?offset={next_offset}", + "previous": None, + } + + +def invoke(method, *args, **kwargs): + result = method(*args, **kwargs) + return asyncio.run(result) if inspect.isawaitable(result) else result + + +def collect(iterator): + async def consume(): + return [item async for item in iterator] + + return asyncio.run(consume()) if hasattr(iterator, "__aiter__") else list(iterator) + + +@pytest.fixture(params=[False, True], ids=["sync", "async"]) +def client(request, monkeypatch): + transport = Mock(spec=SyncTransport) + if request.param: + transport = AsyncMock(spec=AsyncTransport) + monkeypatch.setattr(_client, "AsyncTransport", lambda *args: transport) + evaluations = AsyncOfflineEvaluations(project_id=123, secret_key="phx_example") + else: + monkeypatch.setattr(_client, "SyncTransport", lambda *args: transport) + evaluations = OfflineEvaluations(project_id=123, secret_key="phx_example") + return evaluations, transport + + +def test_dataset_metadata_omission_clearing_and_empty_revision(client): + evaluations, transport = client + response = dataset_response(current_revision=None, current_revision_id=None) + transport.request.return_value = response + dataset = invoke(evaluations.datasets.create, name="Capital cities") + assert dataset.current_revision is None + assert dataset.current_revision_id is None + assert dataset.created_at.tzinfo == timezone.utc + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "name": "Capital cities" + } + assert transport.request.call_args.kwargs["retry_safe"] is False + + response["metadata"]["owner"] = "changed" + assert dataset.metadata == {"owner": "support"} + with pytest.raises(FrozenInstanceError): + dataset.id = OTHER_ITEM_ID + + invoke( + evaluations.datasets.update, + UUID(DATASET_ID), + description="", + metadata={}, + tags=[], + ) + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "description": "", + "metadata": {}, + "tags": [], + } + invoke(evaluations.datasets.update, DATASET_ID, name="Renamed") + assert json.loads(transport.request.call_args.kwargs["body"]) == {"name": "Renamed"} + assert transport.request.call_args.kwargs["retry_safe"] is False + + +@pytest.mark.parametrize("input", [False, 0, "", [], {"messages": []}]) +def test_item_creation_preserves_json_values_and_source_provenance(client, input): + evaluations, transport = client + transport.request.return_value = item_response(input=input) + item = invoke( + evaluations.datasets.create_item, + DATASET_ID, + input=input, + expected_output=None, + source_output="original", + metadata={}, + client_item_id="capital-france", + source_trace_id="trace", + source_event_id="event", + source_timestamp=datetime(2026, 10, 20, tzinfo=timezone.utc), + ) + body = json.loads(transport.request.call_args.kwargs["body"]) + assert item.input == input + assert body == { + "dataset": DATASET_ID, + "input": input, + "expected_output": None, + "source_output": "original", + "metadata": {}, + "client_item_id": "capital-france", + "source_trace_id": "trace", + "source_event_id": "event", + "source_timestamp": "2026-10-20T00:00:00+00:00", + } + assert transport.request.call_args.kwargs["retry_safe"] is True + + +def test_item_updates_distinguish_omission_from_clear_and_protect_source_fields(client): + evaluations, transport = client + transport.request.return_value = item_response() + invoke( + evaluations.datasets.update_item, + ITEM_ID, + base_version=2, + expected_output=None, + metadata={}, + ) + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "base_version": 2, + "expected_output": None, + "metadata": {}, + } + assert transport.request.call_args.kwargs["retry_safe"] is False + invoke(evaluations.datasets.update_item, ITEM_ID, base_version=2, input="new") + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "base_version": 2, + "input": "new", + } + transport.request.reset_mock() + with pytest.raises(TypeError): + invoke( + evaluations.datasets.update_item, + ITEM_ID, + base_version=2, + source_output="overwrite", + ) + transport.request.assert_not_called() + + +@pytest.mark.parametrize("scope", ["dataset", "item"]) +def test_archive_and_restore_use_explicit_transitions(client, scope): + evaluations, transport = client + namespace = evaluations.datasets + if scope == "dataset": + transport.request.return_value = dataset_response(archived=True) + archived = invoke(namespace.archive, DATASET_ID) + assert transport.request.call_args.args == ( + "POST", + BASE + DATASET_ID + "/archive/", + ) + transport.request.return_value = dataset_response() + restored = invoke(namespace.restore, DATASET_ID) + assert transport.request.call_args.args == ( + "POST", + BASE + DATASET_ID + "/restore/", + ) + else: + transport.request.return_value = item_response(archived=True, version=3) + archived = invoke(namespace.archive_item, ITEM_ID, base_version=2) + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "base_version": 2 + } + transport.request.return_value = item_response(version=4) + restored = invoke( + namespace.restore_item, ITEM_ID, base_version=3, source_version=1 + ) + assert json.loads(transport.request.call_args.kwargs["body"]) == { + "base_version": 3, + "source_version": 1, + } + assert transport.request.call_args.args == ( + "POST", + ITEMS + ITEM_ID + "/restore/", + ) + assert archived.archived is True + assert restored.archived is False + assert all( + call.kwargs["retry_safe"] is False for call in transport.request.call_args_list + ) + + +@pytest.mark.parametrize("tags", [None, [], [" Quality "]]) +@pytest.mark.parametrize("tag_match", ["any", "all"]) +def test_filtered_dataset_pages_keep_continuation_and_normalized_tags( + client, tags, tag_match +): + evaluations, transport = client + transport.request.return_value = page_response( + dataset_response(tags=["quality"]), next_offset=50, count=51 + ) + page = invoke( + evaluations.datasets.list, + search="capital", + archived=True, + order_by="updated_at", + tags=tags, + tag_match=tag_match, + ) + assert page.next_offset == 50 + assert page.count == 51 + assert page.results[0].tags == ("quality",) + assert transport.request.call_args.kwargs["params"] == { + "limit": 50, + "offset": 0, + "search": "capital", + "archived": "true", + "order_by": "updated_at", + **({"tags": json.dumps(tags)} if tags is not None else {}), + **({"tag_match": tag_match} if tags is not None or tag_match != "any" else {}), + } + + +@pytest.mark.parametrize( + "field", ["input", "expected_output", "source_output", "metadata"] +) +def test_item_json_preserves_response_key_order_without_aliasing(client, field): + evaluations, transport = client + value = {"z": [{"y": 1, "b": 2}], "a": 3} + transport.request.return_value = item_response(**{field: value}) + + item = invoke(evaluations.datasets.get_item, ITEM_ID) + copied = getattr(item, field) + assert list(copied) == ["z", "a"] + assert list(copied["z"][0]) == ["y", "b"] + value["z"][0]["y"] = 99 + assert copied["z"][0]["y"] == 1 + + +def test_item_history_and_historical_get_keep_stable_and_version_ids_separate(client): + evaluations, transport = client + transport.request.return_value = page_response( + item_response(), item_response(version=1) + ) + page = invoke(evaluations.datasets.list_item_versions, UUID(ITEM_ID), limit=100) + assert isinstance(page, DatasetItemPage) + assert [row.version for row in page.results] == [2, 1] + assert transport.request.call_args.args == ("GET", ITEMS + ITEM_ID + "/versions/") + transport.request.return_value = item_response() + item = invoke(evaluations.datasets.get_item, UUID(ITEM_ID), revision=3) + assert item.id == ITEM_ID and item.version_id == VERSION_ID + assert item.dataset_revision == 2 + assert transport.request.call_args.kwargs["params"] == {"revision": 3} + + +def test_snapshot_pins_before_iteration_and_never_follows_remote_pagination_urls( + client, +): + evaluations, transport = client + latest = dataset_response() + transport.request.return_value = latest + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID) + assert transport.request.call_count == 1 + assert snapshot.revision == 3 and snapshot.revision_id == REVISION_ID + latest.update(current_revision=4, current_revision_id=OLD_REVISION_ID) + iterator = snapshot.iter_items(page_size=1) + assert transport.request.call_count == 1 + first = page_response(item_response(), next_offset=1, count=2) + first["next"] = "https://untrusted.example/api/?offset=1&revision=4" + transport.request.side_effect = [ + first, + page_response(item_response(id=OTHER_ITEM_ID), count=2), + ] + items = collect(iterator) + assert [item.id for item in items] == [ITEM_ID, OTHER_ITEM_ID] + for call in transport.request.call_args_list[1:]: + assert call.args == ("GET", ITEMS) + assert call.kwargs["params"]["revision"] == 3 + assert call.kwargs["params"]["archived"] == "false" + assert transport.request.call_args.kwargs["params"]["offset"] == 1 + + +def test_historical_snapshot_looks_up_expected_offset_without_scanning(client): + evaluations, transport = client + transport.request.side_effect = [ + dataset_response(current_revision=10_000), + page_response(revision_response(), count=10_000), + ] + + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID, revision=1) + + assert snapshot.revision == 1 and snapshot.revision_id == OLD_REVISION_ID + assert transport.request.call_count == 2 + assert transport.request.call_args.args == ( + "GET", + BASE + DATASET_ID + "/revisions/", + ) + assert transport.request.call_args.kwargs["params"] == {"limit": 1, "offset": 9999} + + +def test_historical_snapshot_falls_back_when_concurrent_writes_shift_offset(client): + evaluations, transport = client + transport.request.side_effect = [ + dataset_response(), + page_response(revision_response(revision=2), next_offset=3, count=4), + page_response( + revision_response(revision=4), + revision_response(revision=3), + revision_response(revision=2), + revision_response(), + ), + ] + + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID, revision=1) + + assert snapshot.revision == 1 and snapshot.revision_id == OLD_REVISION_ID + assert [call.kwargs["params"] for call in transport.request.call_args_list[1:]] == [ + {"limit": 1, "offset": 2}, + {"limit": 100, "offset": 0}, + ] + + +def test_historical_snapshot_resolves_revision_uuid_across_pages(client): + evaluations, transport = client + transport.request.side_effect = [ + dataset_response(), + page_response(count=2), + page_response( + revision_response(id=REVISION_ID, revision=3), next_offset=1, count=2 + ), + page_response(revision_response(), count=2), + page_response(item_response(dataset_revision=1)), + ] + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID, revision=1) + assert snapshot.revision_id == OLD_REVISION_ID + assert transport.request.call_args.kwargs["params"]["offset"] == 1 + assert snapshot.dataset.current_revision == 3 + assert [ + call.kwargs["params"]["offset"] for call in transport.request.call_args_list[1:] + ] == [2, 0, 1] + assert len(collect(snapshot.iter_items())) == 1 + assert transport.request.call_args.kwargs["params"]["revision"] == 1 + + +def test_never_populated_and_missing_revisions_are_distinct_from_empty_snapshot(client): + evaluations, transport = client + transport.request.return_value = dataset_response( + current_revision=None, current_revision_id=None + ) + with pytest.raises(ValueError, match="no revision"): + invoke(evaluations.datasets.snapshot, DATASET_ID) + transport.request.side_effect = [dataset_response(), page_response()] + with pytest.raises(ValueError, match="does not exist"): + invoke(evaluations.datasets.snapshot, DATASET_ID, revision=9) + assert transport.request.call_args.args == ("GET", BASE + DATASET_ID + "/") + transport.request.side_effect = [dataset_response(archived=True), page_response()] + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID) + assert collect(snapshot.iter_items()) == [] + + +def test_missing_historical_revision_stops_once_history_passes_it(client): + evaluations, transport = client + transport.request.side_effect = [ + dataset_response(), + page_response(revision_response(), count=2), + page_response(revision_response(), next_offset=1, count=2), + ] + with pytest.raises(ValueError, match="revision 2 does not exist"): + invoke(evaluations.datasets.snapshot, DATASET_ID, revision=2) + assert transport.request.call_count == 3 + + +def test_snapshot_propagates_partial_read_failure_and_can_be_iterated_again(client): + evaluations, transport = client + transport.request.return_value = dataset_response() + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID) + failure = EvaluationAPIError(status=503, persistence="unknown") + transport.request.side_effect = [ + page_response(item_response(), next_offset=1, count=2), + failure, + ] + with pytest.raises(EvaluationAPIError) as caught: + collect(snapshot.iter_items(page_size=1)) + assert caught.value is failure + transport.request.side_effect = [page_response(item_response())] + assert len(collect(snapshot.iter_items())) == 1 + assert transport.request.call_args.kwargs["params"]["offset"] == 0 + + +@pytest.mark.parametrize( + "next_url,rows", + [ + ("?offset=0", [item_response()]), + ("?offset=-1", [item_response()]), + ("?offset=one", [item_response()]), + ("?offset=1&offset=2", [item_response()]), + ("?cursor=next", [item_response()]), + ("?offset=1", []), + ], +) +def test_invalid_continuations_cannot_loop_or_silently_truncate(client, next_url, rows): + evaluations, transport = client + transport.request.return_value = {"count": 2, "results": rows, "next": next_url} + with pytest.raises(EvaluationAPIError, match="no acknowledgment") as caught: + invoke(evaluations.datasets.list_items, DATASET_ID) + assert caught.value.code == "invalid_response" + + +@pytest.mark.parametrize( + "overrides", + [ + {"dataset": OTHER_ITEM_ID}, + {"team_id": 999}, + {"dataset_revision": 4}, + {"archived": True}, + {"version_id": "invalid"}, + {"metadata": []}, + {"input": None}, + {"version": True}, + {"created_at": "2026-10-20"}, + ], +) +def test_invalid_item_responses_cannot_enter_a_pinned_run(client, overrides): + evaluations, transport = client + transport.request.return_value = page_response(item_response(**overrides)) + with pytest.raises(EvaluationAPIError) as caught: + invoke(evaluations.datasets.list_items, DATASET_ID, revision=3) + assert caught.value.code == "invalid_response" + assert caught.value.persistence == "unknown" + assert caught.value.detail == "The dataset API returned an invalid response." + assert caught.value.response == transport.request.return_value + + +@pytest.mark.parametrize( + "overrides", + [ + {"id": OTHER_ITEM_ID}, + {"team_id": 999}, + {"current_revision": None}, + {"current_revision_id": None}, + {"current_revision": True}, + ], +) +def test_invalid_dataset_metadata_cannot_pin_a_snapshot(client, overrides): + evaluations, transport = client + transport.request.return_value = dataset_response(**overrides) + with pytest.raises(EvaluationAPIError) as caught: + invoke(evaluations.datasets.snapshot, DATASET_ID) + assert caught.value.code == "invalid_response" + + +@pytest.mark.parametrize( + "method,args,kwargs", + [ + ("create", (), {"name": " "}), + ("update", (DATASET_ID,), {"description": None}), + ("update", (DATASET_ID,), {"metadata": None}), + ("update", (DATASET_ID,), {"tags": "tag"}), + ("get", ("../other-project",), {}), + ("list", (), {"limit": 101}), + ("list", (), {"offset": -1}), + ("list", (), {"archived": "false"}), + ("list", (), {"tag_match": "invalid"}), + ("list_items", (DATASET_ID,), {"limit": 26}), + ("list_items", (DATASET_ID,), {"revision": 0}), + ("snapshot", (DATASET_ID,), {"revision": True}), + ("create_item", (DATASET_ID,), {"input": None}), + ("create_item", (DATASET_ID,), {"input": float("nan")}), + ("create_item", (DATASET_ID,), {"input": {1: "invalid key"}}), + ("create_item", (DATASET_ID,), {"input": "q", "client_item_id": ""}), + ("create_item", (DATASET_ID,), {"input": "q", "source_trace_id": "trace"}), + ("create_item", (DATASET_ID,), {"input": "q", "source_event_id": "event"}), + ("create_item", (DATASET_ID,), {"input": "q", "source_timestamp": TIMESTAMP}), + ( + "create_item", + (DATASET_ID,), + { + "input": "q", + "source_trace_id": "trace", + "source_timestamp": "2026-10-20", + }, + ), + ("update_item", (ITEM_ID,), {"base_version": 0}), + ("update_item", (ITEM_ID,), {"base_version": 2, "input": None}), + ("restore_item", (ITEM_ID,), {"base_version": 2, "source_version": False}), + ], +) +def test_invalid_requests_fail_before_network_io(client, method, args, kwargs): + evaluations, transport = client + with pytest.raises(ValueError): + invoke(getattr(evaluations.datasets, method), *args, **kwargs) + transport.request.assert_not_called() + + +def test_conflicts_and_scope_errors_preserve_actionable_server_details(client): + evaluations, transport = client + conflict = EvaluationAPIError( + status=409, + code="stale_version", + response={"current_version": 3, "current_item_id": ITEM_ID}, + persistence="rejected", + ) + transport.request.side_effect = conflict + with pytest.raises(EvaluationAPIError) as caught: + invoke( + evaluations.datasets.update_item, + ITEM_ID, + base_version=2, + expected_output="new", + ) + assert caught.value is conflict + assert caught.value.response["current_version"] == 3 + transport.request.assert_called_once() + transport.request.side_effect = EvaluationAPIError( + status=403, persistence="rejected" + ) + with pytest.raises(EvaluationAPIError) as caught: + invoke(evaluations.datasets.get, DATASET_ID) + assert caught.value.status == 403 + + +def test_dataset_to_execution_copies_payload_and_keeps_trials_independent(client): + evaluations, transport = client + response = item_response() + transport.request.return_value = response + case = invoke(evaluations.datasets.get_item, ITEM_ID) + original = copy.deepcopy(response) + response["metadata"]["category"].append("changed") + output = {"answer": "Paris"} + first = EvaluationItem.from_dataset_item( + case, output=output, trial="1", application_trace_id="new-trace" + ) + second = EvaluationItem.from_dataset_item(case, output="Paris", trial="2") + assert first.id != second.id and first.id != case.id + data = first.to_dict() + assert data["dataset_item_version_id"] == VERSION_ID + assert data["dataset_item_identifier"] == ITEM_ID + assert data["dataset_item_version_identifier"] == VERSION_ID + assert data["case_key"] == "capital-france" + assert data["application_trace_id"] == "new-trace" + assert data["payload"] == { + "input": original["input"], + "output": output, + "expected_output": "Paris", + "metadata": original["metadata"], + } + output["answer"] = "changed" + case.metadata["category"].append("changed locally") + assert first.to_dict() == data + assert "application_trace_id" not in second.to_dict() + assert EvaluationItem.from_dict(data).to_dict() == data + assert ( + EvaluationItem.from_dataset_item(replace(case, client_item_id=None)).to_dict()[ + "case_key" + ] + == ITEM_ID + ) + assert "output" not in EvaluationItem.from_dataset_item(case).to_dict()["payload"] + explicit = EvaluationItem.from_dataset_item( + case, id=first.id, case_key="override", output=None + ) + assert explicit.id == first.id + assert explicit.to_dict()["case_key"] == "override" + assert explicit.to_dict()["payload"]["output"] is None + with pytest.raises(ValueError, match="Archived"): + EvaluationItem.from_dataset_item(replace(case, archived=True)) + + +def test_dataset_scorer_experiment_flow_pins_both_versions_and_reuses_execution(client): + evaluations, transport = client + bodies = [] + + def respond(method, path, *, body=None, **kwargs): + if path == BASE + DATASET_ID + "/": + return dataset_response() + if path == ITEMS: + return page_response(item_response()) + if "score_definitions" in path: + return scorer_response() + if path.endswith("/upload/"): + bodies.append(json.loads(body)) + return respond_to_experiment(method, path, body=body, **kwargs) + + transport.request.side_effect = respond + snapshot = invoke(evaluations.datasets.snapshot, DATASET_ID) + scorer = invoke(evaluations.scorers.get, scorer_response()["id"]) + experiment = invoke( + evaluations.create_experiment, + name="Capital cities", + dataset_revision_id=snapshot.revision_id, + ) + case = collect(snapshot.iter_items())[0] + item = EvaluationItem.from_dataset_item(case, output="Paris") + results = [ + EvaluationResult(item=item, scorer_version_id=version, value=True) + for version in [scorer.current_version_id, OTHER_ITEM_ID] + ] + invoke(experiment.upload_results, results) + invoke(experiment.complete) + assert experiment.submission["dataset_revision_id"] == REVISION_ID + assert experiment.submission["dataset_revision_id"] != case.dataset_revision_id + assert len(bodies[0]["items"]) == 1 + assert {result["item_id"] for result in bodies[0]["results"]} == {item.id} + assert bodies[0]["items"][0]["dataset_item_version_id"] == VERSION_ID + + +@pytest.mark.parametrize("asynchronous", [False, True], ids=["sync", "async"]) +@pytest.mark.parametrize("client_item_id", [None, "stable-key"]) +def test_lost_item_create_acknowledgment_only_retries_with_explicit_identity( + asynchronous, client_item_id +): + attempts = [] + + def payload(attempt): + attempts.append(attempt) + if len(attempts) == 1: + raise ( + requests.ReadTimeout() + if not asynchronous + else httpx.ReadTimeout("lost acknowledgment") + ) + return item_response(client_item_id=client_item_id) + + async def run_async(): + async with AsyncOfflineEvaluations( + project_id=123, secret_key="phx_example" + ) as evaluations: + + def respond(request): + return httpx.Response(200, json=payload((request.url, request.content))) + + await evaluations._transport._client.aclose() + evaluations._transport._client = httpx.AsyncClient( + transport=httpx.MockTransport(respond) + ) + with patch( + "posthog.ai.evaluations._transport.asyncio.sleep", + new_callable=AsyncMock, + ): + return await evaluations.datasets.create_item( + DATASET_ID, input="q", client_item_id=client_item_id + ) + + def run_sync(): + with OfflineEvaluations( + project_id=123, secret_key="phx_example" + ) as evaluations: + + def respond(method, url, **kwargs): + data = payload((url, kwargs["data"])) + result = requests.Response() + result.status_code = 200 + result._content = json.dumps(data).encode() + return result + + with ( + patch.object( + evaluations._transport._session, "request", side_effect=respond + ), + patch("posthog.ai.evaluations._transport.time.sleep"), + ): + return evaluations.datasets.create_item( + DATASET_ID, input="q", client_item_id=client_item_id + ) + + def run(): + return asyncio.run(run_async()) if asynchronous else run_sync() + + if client_item_id is None: + with pytest.raises(EvaluationAPIError) as caught: + run() + assert caught.value.persistence == "unknown" + assert len(attempts) == 1 + else: + assert run().id == ITEM_ID + assert len(attempts) == 2 + assert attempts[0] == attempts[1] + + +def test_dataset_example_replays_persisted_cases_without_refetching_or_rerunning( + monkeypatch, tmp_path +): + example = Path(__file__).parents[3] / "examples/example-offline-evaluations/main.py" + spec = importlib.util.spec_from_file_location("dataset_evaluation_example", example) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + state_path = tmp_path / "dataset-run.json" + monkeypatch.setenv("POSTHOG_PROJECT_ID", "123") + monkeypatch.setenv("POSTHOG_SECRET_KEY", "never-save-this-secret") + monkeypatch.setenv("POSTHOG_HOST", "https://us.posthog.com") + monkeypatch.setenv("POSTHOG_SCORER_VERSION_ID", VERSION_ID) + monkeypatch.setattr( + "sys.argv", + [str(example), "--dataset-id", DATASET_ID, "--state", str(state_path)], + ) + transport = Mock(spec=SyncTransport) + monkeypatch.setattr(_client, "SyncTransport", lambda *args: transport) + + def respond(method, path, **kwargs): + if method == "GET": + assert not state_path.exists() + if path == BASE + DATASET_ID + "/": + return dataset_response() + return page_response(item_response(input="Capital of France?")) + assert state_path.exists() + assert "never-save-this-secret" not in state_path.read_text() + return respond_to_experiment(method, path, **kwargs) + + transport.request.side_effect = respond + module.main() + state = json.loads(state_path.read_text()) + assert state["experiment"]["dataset_revision_id"] == REVISION_ID + assert state["items"][0]["dataset_item_version_id"] == VERSION_ID + assert state["results"][0]["value"] is True + first_writes = [ + call for call in transport.request.call_args_list if call.args[0] == "POST" + ] + transport.request.reset_mock() + monkeypatch.setattr( + module, + "capital_answer", + Mock(side_effect=AssertionError("Execution must not replay")), + ) + module.main() + assert transport.request.call_args_list == first_writes + + +@pytest.mark.parametrize("asynchronous", [False, True], ids=["sync", "async"]) +def test_snapshot_cannot_read_after_owning_client_closes(asynchronous): + async def run_async(): + async with AsyncOfflineEvaluations( + project_id=123, secret_key="phx_example" + ) as evaluations: + with patch.object( + evaluations._transport, + "request", + new_callable=AsyncMock, + return_value=dataset_response(), + ): + snapshot = await evaluations.datasets.snapshot(DATASET_ID) + return [item async for item in snapshot.iter_items()] + + def run_sync(): + with OfflineEvaluations( + project_id=123, secret_key="phx_example" + ) as evaluations: + with patch.object( + evaluations._transport, "request", return_value=dataset_response() + ): + snapshot = evaluations.datasets.snapshot(DATASET_ID) + return list(snapshot.iter_items()) + + with pytest.raises(EvaluationAPIError) as caught: + asyncio.run(run_async()) if asynchronous else run_sync() + assert caught.value.code == "client_closed" + assert caught.value.persistence == "not_sent" diff --git a/posthog/test/ai/test_evaluations_scorers.py b/posthog/test/ai/test_evaluations_scorers.py index 9fa40e918..54cf97bac 100644 --- a/posthog/test/ai/test_evaluations_scorers.py +++ b/posthog/test/ai/test_evaluations_scorers.py @@ -214,7 +214,7 @@ def test_invalid_scorer_response_tags_raise(scorers, tags): @pytest.mark.parametrize("tag_match", ["any", "all"]) -@pytest.mark.parametrize("tags", [[], ("quality", 'a,b"c', "品質")]) +@pytest.mark.parametrize("tags", [None, [], ("quality", 'a,b"c', "品質")]) def test_scorer_list_tag_filters_use_json_and_preserve_other_filters( scorers, tags, tag_match ): @@ -229,8 +229,14 @@ def test_scorer_list_tag_filters_use_json_and_preserve_other_filters( namespace.list, tags=tags, tag_match=tag_match, offset=3, search="score" ) params = transport.request.call_args.kwargs["params"] - assert json.loads(params["tags"]) == list(tags) - assert params["tag_match"] == tag_match + if tags is None: + assert "tags" not in params + else: + assert json.loads(params["tags"]) == list(tags) + if tags is None and tag_match == "any": + assert "tag_match" not in params + else: + assert params["tag_match"] == tag_match assert params["offset"] == 3 assert params["search"] == "score" assert page.results[0].tags == ("quality",) @@ -418,6 +424,8 @@ def test_malformed_success_preserves_unknown_persistence(scorers, override): ) assert caught.value.code == "invalid_response" assert caught.value.persistence == "unknown" + assert caught.value.detail == "The scorer API returned an invalid response." + assert caught.value.response == transport.request.return_value assert "Quality" not in str(caught.value) transport.request.assert_called_once() diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index d62d611c5..7d4079051 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -378,9 +378,13 @@ attribute posthog.ai.anthropic.anthropic_providers.AsyncAnthropicBedrock.message attribute posthog.ai.anthropic.anthropic_providers.AsyncAnthropicVertex.messages = AsyncWrappedMessages(self) attribute posthog.ai.claude_agent_sdk.client.log = logging.getLogger('posthog') attribute posthog.ai.claude_agent_sdk.processor.log = logging.getLogger('posthog') +attribute posthog.ai.evaluations.AsyncDatasetSnapshot.dataset: Dataset +attribute posthog.ai.evaluations.AsyncDatasetSnapshot.revision: int +attribute posthog.ai.evaluations.AsyncDatasetSnapshot.revision_id: str attribute posthog.ai.evaluations.AsyncExperiment.id: str attribute posthog.ai.evaluations.AsyncExperiment.receipt = receipt attribute posthog.ai.evaluations.AsyncExperiment.submission: dict[str, Any] | None +attribute posthog.ai.evaluations.AsyncOfflineEvaluations.datasets = AsyncDatasets(self._transport, project_id) attribute posthog.ai.evaluations.AsyncOfflineEvaluations.scorers = AsyncScorers(self._transport, project_id) attribute posthog.ai.evaluations.BooleanScorerConfig.false_label: str attribute posthog.ai.evaluations.BooleanScorerConfig.true_is_failure: bool | None @@ -398,6 +402,58 @@ attribute posthog.ai.evaluations.CategoricalScorerConfig.passing_rule: Categoric attribute posthog.ai.evaluations.CategoricalScorerConfig.selection_mode: Literal['single', 'multiple'] attribute posthog.ai.evaluations.CategoricalScorerOption.key: str attribute posthog.ai.evaluations.CategoricalScorerOption.label: str +attribute posthog.ai.evaluations.Dataset.archived: bool +attribute posthog.ai.evaluations.Dataset.created_at: datetime +attribute posthog.ai.evaluations.Dataset.created_by: dict[str, Any] | None +attribute posthog.ai.evaluations.Dataset.current_revision: int | None +attribute posthog.ai.evaluations.Dataset.current_revision_id: str | None +attribute posthog.ai.evaluations.Dataset.description: str +attribute posthog.ai.evaluations.Dataset.id: str +attribute posthog.ai.evaluations.Dataset.metadata: dict[str, JSONValue] = field(repr=False) +attribute posthog.ai.evaluations.Dataset.name: str +attribute posthog.ai.evaluations.Dataset.tags: tuple[str, ...] +attribute posthog.ai.evaluations.Dataset.team_id: int +attribute posthog.ai.evaluations.Dataset.updated_at: datetime | None +attribute posthog.ai.evaluations.DatasetItem.archived: bool +attribute posthog.ai.evaluations.DatasetItem.client_item_id: str | None +attribute posthog.ai.evaluations.DatasetItem.created_at: datetime +attribute posthog.ai.evaluations.DatasetItem.created_by: dict[str, Any] | None +attribute posthog.ai.evaluations.DatasetItem.dataset_id: str +attribute posthog.ai.evaluations.DatasetItem.dataset_revision: int +attribute posthog.ai.evaluations.DatasetItem.dataset_revision_id: str +attribute posthog.ai.evaluations.DatasetItem.expected_output: JSONValue = field(repr=False) +attribute posthog.ai.evaluations.DatasetItem.id: str +attribute posthog.ai.evaluations.DatasetItem.input: JSONValue = field(repr=False) +attribute posthog.ai.evaluations.DatasetItem.metadata: dict[str, JSONValue] = field(repr=False) +attribute posthog.ai.evaluations.DatasetItem.source_event_id: str | None +attribute posthog.ai.evaluations.DatasetItem.source_output: JSONValue = field(repr=False) +attribute posthog.ai.evaluations.DatasetItem.source_timestamp: datetime | None +attribute posthog.ai.evaluations.DatasetItem.source_trace_id: str | None +attribute posthog.ai.evaluations.DatasetItem.team_id: int +attribute posthog.ai.evaluations.DatasetItem.updated_at: datetime | None +attribute posthog.ai.evaluations.DatasetItem.version: int +attribute posthog.ai.evaluations.DatasetItem.version_created_at: datetime +attribute posthog.ai.evaluations.DatasetItem.version_created_by: dict[str, Any] | None +attribute posthog.ai.evaluations.DatasetItem.version_id: str +attribute posthog.ai.evaluations.DatasetItemPage.count: int +attribute posthog.ai.evaluations.DatasetItemPage.next_offset: int | None +attribute posthog.ai.evaluations.DatasetItemPage.results: tuple[DatasetItem, ...] +attribute posthog.ai.evaluations.DatasetOrder = Literal['created_at', '-created_at', 'updated_at', '-updated_at'] +attribute posthog.ai.evaluations.DatasetPage.count: int +attribute posthog.ai.evaluations.DatasetPage.next_offset: int | None +attribute posthog.ai.evaluations.DatasetPage.results: tuple[Dataset, ...] +attribute posthog.ai.evaluations.DatasetRevision.created_at: datetime +attribute posthog.ai.evaluations.DatasetRevision.created_by: dict[str, Any] | None +attribute posthog.ai.evaluations.DatasetRevision.dataset_id: str +attribute posthog.ai.evaluations.DatasetRevision.id: str +attribute posthog.ai.evaluations.DatasetRevision.revision: int +attribute posthog.ai.evaluations.DatasetRevision.team_id: int +attribute posthog.ai.evaluations.DatasetRevisionPage.count: int +attribute posthog.ai.evaluations.DatasetRevisionPage.next_offset: int | None +attribute posthog.ai.evaluations.DatasetRevisionPage.results: tuple[DatasetRevision, ...] +attribute posthog.ai.evaluations.DatasetSnapshot.dataset: Dataset +attribute posthog.ai.evaluations.DatasetSnapshot.revision: int +attribute posthog.ai.evaluations.DatasetSnapshot.revision_id: str attribute posthog.ai.evaluations.EvaluationAPIError.attr = attr attribute posthog.ai.evaluations.EvaluationAPIError.code = code attribute posthog.ai.evaluations.EvaluationAPIError.detail = deepcopy(detail) @@ -447,6 +503,7 @@ attribute posthog.ai.evaluations.NumericScorerConfig.max: float | None attribute posthog.ai.evaluations.NumericScorerConfig.min: float | None attribute posthog.ai.evaluations.NumericScorerConfig.passing_rule: NumericPassingRule | None attribute posthog.ai.evaluations.NumericScorerConfig.step: float | None +attribute posthog.ai.evaluations.OfflineEvaluations.datasets = Datasets(self._transport, project_id) attribute posthog.ai.evaluations.OfflineEvaluations.scorers = Scorers(self._transport, project_id) attribute posthog.ai.evaluations.ResultOptions.error_code: str | None attribute posthog.ai.evaluations.ResultOptions.error_message: str | None @@ -1120,6 +1177,8 @@ class posthog.ai.anthropic.anthropic_providers.AsyncAnthropicBedrock(posthog_cli class posthog.ai.anthropic.anthropic_providers.AsyncAnthropicVertex(posthog_client: Optional[PostHogClient] = None, **kwargs) class posthog.ai.claude_agent_sdk.client.PostHogClaudeSDKClient(options: Optional[ClaudeAgentOptions] = None, transport: Any = None, *, posthog_client: Optional[Client] = None, posthog_distinct_id: Optional[Union[str, Callable[[ResultMessage], Optional[str]]]] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: bool = False, posthog_groups: Optional[Dict[str, Any]] = None) class posthog.ai.claude_agent_sdk.processor.PostHogClaudeAgentProcessor(client: Optional[Client] = None, distinct_id: Optional[Union[str, Callable[[ResultMessage], Optional[str]]]] = None, privacy_mode: bool = False, groups: Optional[Dict[str, Any]] = None, properties: Optional[Dict[str, Any]] = None) +class posthog.ai.evaluations.AsyncDatasetSnapshot(dataset: Dataset, revision: int, revision_id: str, _datasets: AsyncDatasets) +class posthog.ai.evaluations.AsyncDatasets(transport: AsyncTransport, project_id: int) class posthog.ai.evaluations.AsyncExperiment(transport: AsyncTransport, project_id: int, id: str, *, receipt: ExperimentReceipt | None = None, submission: bytes | None = None) class posthog.ai.evaluations.AsyncOfflineEvaluations(*, project_id: int, secret_key: str, host: str | None = None, timeout: float = 15, max_retries: int = 3) class posthog.ai.evaluations.AsyncScorers(transport: AsyncTransport, project_id: int) @@ -1129,6 +1188,14 @@ class posthog.ai.evaluations.BulkUploadReceipt(chunks: tuple[UploadReceipt, ...] class posthog.ai.evaluations.CategoricalPassingRule class posthog.ai.evaluations.CategoricalScorerConfig class posthog.ai.evaluations.CategoricalScorerOption +class posthog.ai.evaluations.Dataset(id: str, name: str, description: str, metadata: dict[str, JSONValue], tags: tuple[str, ...], archived: bool, current_revision: int | None, current_revision_id: str | None, created_at: datetime, updated_at: datetime | None, created_by: dict[str, Any] | None, team_id: int) +class posthog.ai.evaluations.DatasetItem(id: str, dataset_id: str, client_item_id: str | None, version: int, version_id: str, dataset_revision: int, dataset_revision_id: str, archived: bool, input: JSONValue, expected_output: JSONValue, source_output: JSONValue, metadata: dict[str, JSONValue], source_trace_id: str | None, source_event_id: str | None, source_timestamp: datetime | None, created_at: datetime, updated_at: datetime | None, created_by: dict[str, Any] | None, version_created_at: datetime, version_created_by: dict[str, Any] | None, team_id: int) +class posthog.ai.evaluations.DatasetItemPage(count: int, results: tuple[DatasetItem, ...], next_offset: int | None) +class posthog.ai.evaluations.DatasetPage(count: int, results: tuple[Dataset, ...], next_offset: int | None) +class posthog.ai.evaluations.DatasetRevision(id: str, dataset_id: str, revision: int, created_at: datetime, created_by: dict[str, Any] | None, team_id: int) +class posthog.ai.evaluations.DatasetRevisionPage(count: int, results: tuple[DatasetRevision, ...], next_offset: int | None) +class posthog.ai.evaluations.DatasetSnapshot(dataset: Dataset, revision: int, revision_id: str, _datasets: Datasets) +class posthog.ai.evaluations.Datasets(transport: SyncTransport, project_id: int) class posthog.ai.evaluations.EvaluationAPIError(*, status: int | None = None, code: str | None = None, detail: Any = None, attr: str | None = None, errors: Any = None, response: dict[str, Any] | None = None, retry_after: float | None = None, persistence: Literal['rejected', 'unknown', 'not_sent'] = 'unknown', submission: dict[str, Any] | None = None) class posthog.ai.evaluations.EvaluationItem(*, id: str | UUID | None = None, input: JSONValue | _Unset = _UNSET, output: JSONValue | _Unset = _UNSET, expected_output: JSONValue | _Unset = _UNSET, metadata: dict[str, JSONValue] | None | _Unset = _UNSET, case_key: str | None = None, trial: str | None = None, dataset_item_identifier: str | None = None, dataset_item_version_identifier: str | None = None, dataset_item_version_id: str | UUID | None = None, application_trace_id: str | None = None, payload: dict[str, JSONValue] | _Unset = _UNSET) class posthog.ai.evaluations.EvaluationResult(*, item: EvaluationItem | str | UUID, scorer_version_id: str | UUID, value: ScoreValue | None = None, status: ResultStatus = 'ok', error_code: str | None = None, reasoning: str | None | _Unset = _UNSET, error_message: str | None | _Unset = _UNSET, metadata: dict[str, JSONValue] | None | _Unset = _UNSET, evaluator_trace_id: str | None = None, evaluated_at: datetime | str | None = None, payload: dict[str, JSONValue] | _Unset = _UNSET) @@ -1496,6 +1563,22 @@ method posthog.ai.claude_agent_sdk.client.PostHogClaudeSDKClient.receive_respons method posthog.ai.claude_agent_sdk.client.PostHogClaudeSDKClient.set_model(model: Optional[str] = None) -> None method posthog.ai.claude_agent_sdk.client.PostHogClaudeSDKClient.set_permission_mode(mode: str) -> None method posthog.ai.claude_agent_sdk.processor.PostHogClaudeAgentProcessor.query(*, prompt: Any, options: Optional[ClaudeAgentOptions] = None, transport: Any = None, posthog_distinct_id: Optional[Union[str, Callable[[ResultMessage], Optional[str]]]] = None, posthog_trace_id: Optional[str] = None, posthog_properties: Optional[Dict[str, Any]] = None, posthog_privacy_mode: Optional[bool] = None, posthog_groups: Optional[Dict[str, Any]] = None) +method posthog.ai.evaluations.AsyncDatasetSnapshot.iter_items(*, page_size: int = 25) +method posthog.ai.evaluations.AsyncDatasets.archive(dataset_id: str | UUID) +method posthog.ai.evaluations.AsyncDatasets.archive_item(item_id: str | UUID, *, base_version: int) +method posthog.ai.evaluations.AsyncDatasets.create(*, name: str, description: str | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, tags: Sequence[str] | _Unset = _UNSET) +method posthog.ai.evaluations.AsyncDatasets.create_item(dataset_id: str | UUID, *, input: JSONValue, expected_output: JSONValue | _Unset = _UNSET, source_output: JSONValue | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, client_item_id: str | None = None, source_trace_id: str | None = None, source_event_id: str | None = None, source_timestamp: datetime | str | None = None) +method posthog.ai.evaluations.AsyncDatasets.get(dataset_id: str | UUID) +method posthog.ai.evaluations.AsyncDatasets.get_item(item_id: str | UUID, *, revision: int | None = None) +method posthog.ai.evaluations.AsyncDatasets.list(*, limit: int = 50, offset: int = 0, search: str | None = None, archived: bool = False, order_by: DatasetOrder = '-created_at', tags: Sequence[str] | None = None, tag_match: Literal['any', 'all'] = 'any') +method posthog.ai.evaluations.AsyncDatasets.list_item_versions(item_id: str | UUID, *, limit: int = 25, offset: int = 0) +method posthog.ai.evaluations.AsyncDatasets.list_items(dataset_id: str | UUID, *, revision: int | None = None, archived: bool = False, limit: int = 25, offset: int = 0) +method posthog.ai.evaluations.AsyncDatasets.list_revisions(dataset_id: str | UUID, *, limit: int = 50, offset: int = 0) +method posthog.ai.evaluations.AsyncDatasets.restore(dataset_id: str | UUID) +method posthog.ai.evaluations.AsyncDatasets.restore_item(item_id: str | UUID, *, base_version: int, source_version: int | None = None) +method posthog.ai.evaluations.AsyncDatasets.snapshot(dataset_id: str | UUID, *, revision: int | None = None) +method posthog.ai.evaluations.AsyncDatasets.update(dataset_id: str | UUID, *, name: str | _Unset = _UNSET, description: str | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, tags: Sequence[str] | _Unset = _UNSET) +method posthog.ai.evaluations.AsyncDatasets.update_item(item_id: str | UUID, *, base_version: int, input: JSONValue | _Unset = _UNSET, expected_output: JSONValue | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET) method posthog.ai.evaluations.AsyncExperiment.complete() method posthog.ai.evaluations.AsyncExperiment.fail() method posthog.ai.evaluations.AsyncExperiment.get_tags() @@ -1512,6 +1595,23 @@ method posthog.ai.evaluations.AsyncScorers.get_version(scorer_id: str | UUID, ve method posthog.ai.evaluations.AsyncScorers.list(*, limit: int = 100, offset: int = 0, search: str | None = None, kind: ScorerKind | None = None, archived: bool | None = None, order_by: ScorerOrder | None = None, tags: Sequence[str] | None = None, tag_match: Literal['any', 'all'] = 'any') method posthog.ai.evaluations.AsyncScorers.list_versions(scorer_id: str | UUID, *, limit: int = 50, cursor: str | None = None) method posthog.ai.evaluations.AsyncScorers.update(scorer_id: str | UUID, *, name: str | _Omitted = _OMITTED, description: str | None | _Omitted = _OMITTED, archived: bool | _Omitted = _OMITTED, tags: Sequence[str] | _Omitted = _OMITTED) +method posthog.ai.evaluations.DatasetSnapshot.iter_items(*, page_size: int = 25) +method posthog.ai.evaluations.Datasets.archive(dataset_id: str | UUID) +method posthog.ai.evaluations.Datasets.archive_item(item_id: str | UUID, *, base_version: int) +method posthog.ai.evaluations.Datasets.create(*, name: str, description: str | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, tags: Sequence[str] | _Unset = _UNSET) +method posthog.ai.evaluations.Datasets.create_item(dataset_id: str | UUID, *, input: JSONValue, expected_output: JSONValue | _Unset = _UNSET, source_output: JSONValue | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, client_item_id: str | None = None, source_trace_id: str | None = None, source_event_id: str | None = None, source_timestamp: datetime | str | None = None) +method posthog.ai.evaluations.Datasets.get(dataset_id: str | UUID) +method posthog.ai.evaluations.Datasets.get_item(item_id: str | UUID, *, revision: int | None = None) +method posthog.ai.evaluations.Datasets.list(*, limit: int = 50, offset: int = 0, search: str | None = None, archived: bool = False, order_by: DatasetOrder = '-created_at', tags: Sequence[str] | None = None, tag_match: Literal['any', 'all'] = 'any') +method posthog.ai.evaluations.Datasets.list_item_versions(item_id: str | UUID, *, limit: int = 25, offset: int = 0) +method posthog.ai.evaluations.Datasets.list_items(dataset_id: str | UUID, *, revision: int | None = None, archived: bool = False, limit: int = 25, offset: int = 0) +method posthog.ai.evaluations.Datasets.list_revisions(dataset_id: str | UUID, *, limit: int = 50, offset: int = 0) +method posthog.ai.evaluations.Datasets.restore(dataset_id: str | UUID) +method posthog.ai.evaluations.Datasets.restore_item(item_id: str | UUID, *, base_version: int, source_version: int | None = None) +method posthog.ai.evaluations.Datasets.snapshot(dataset_id: str | UUID, *, revision: int | None = None) +method posthog.ai.evaluations.Datasets.update(dataset_id: str | UUID, *, name: str | _Unset = _UNSET, description: str | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET, tags: Sequence[str] | _Unset = _UNSET) +method posthog.ai.evaluations.Datasets.update_item(item_id: str | UUID, *, base_version: int, input: JSONValue | _Unset = _UNSET, expected_output: JSONValue | _Unset = _UNSET, metadata: dict[str, JSONValue] | _Unset = _UNSET) +method posthog.ai.evaluations.EvaluationItem.from_dataset_item(item: DatasetItem, *, output: JSONValue | _Unset = _UNSET, id: str | UUID | None = None, case_key: str | None = None, trial: str | None = None, application_trace_id: str | None = None) method posthog.ai.evaluations.EvaluationItem.from_dict(data: Mapping[str, Any]) method posthog.ai.evaluations.EvaluationItem.to_dict() method posthog.ai.evaluations.EvaluationResult.from_dict(data: Mapping[str, Any], *, item: EvaluationItem | None = None) From 43810584681f66538eaf78947b9d7a9abfa13769 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 14:39:33 +0000 Subject: [PATCH 42/70] chore: Release v7.74.0 [skip ci] (cherry picked from commit ac7fa9955ce1dc6f2f11b0d36017eb65727624a1) --- .sampo/changesets/ai-evaluation-datasets.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/ai-evaluation-datasets.md diff --git a/.sampo/changesets/ai-evaluation-datasets.md b/.sampo/changesets/ai-evaluation-datasets.md deleted file mode 100644 index 22d689b31..000000000 --- a/.sampo/changesets/ai-evaluation-datasets.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -Manage AI observability datasets and items through `OfflineEvaluations.datasets` and `AsyncOfflineEvaluations.datasets`, including history, tags, and archive/restore operations. Pin a dataset snapshot for lazy, consistent reads and use `EvaluationItem.from_dataset_item()` to preserve case provenance across offline experiments and scorers. Item creates with a caller-supplied `client_item_id` support safe retries; updates use explicit version checks. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index eae14033a..eb45ccb44 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.113 — 2026-10-21 + +### Patch changes + +- Updated dependencies: posthog@7.74.0 + ## 0.1.112 — 2026-10-21 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 92d376079..5a00661cf 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.112" +version = "0.1.113" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index ef5cff2d4..9b6467603 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.74.0 — 2026-10-21 + +### Minor changes + +- [b8879a7](https://github.com/posthog/posthog-python/commit/b8879a7550e1bc2728bb5d23d8ddb215ba3602a7) Manage AI observability datasets and items through `OfflineEvaluations.datasets` and `AsyncOfflineEvaluations.datasets`, including history, tags, and archive/restore operations. Pin a dataset snapshot for lazy, consistent reads and use `EvaluationItem.from_dataset_item()` to preserve case provenance across offline experiments and scorers. Item creates with a caller-supplied `client_item_id` support safe retries; updates use explicit version checks. — Thanks @Radu-Raicea! + ## 7.73.3 — 2026-10-21 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index 94c1d369b..bf1e6fa9c 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.73.3" +VERSION = "7.74.0" diff --git a/pyproject.toml b/pyproject.toml index f36cef857..cc49bbaf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.73.3" +version = "7.74.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index bf64fcfc8..40ac6fc46 100644 --- a/uv.lock +++ b/uv.lock @@ -2533,7 +2533,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.112" +version = "0.1.113" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -2863,7 +2863,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.3" +version = "7.74.0" source = { editable = "." } dependencies = [ { name = "distro" }, From f4473b6acb183b3590f8844cbfc779d1a5d64140 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 14:39:38 +0000 Subject: [PATCH 43/70] Update generated references (cherry picked from commit b14dd9e3f00c06af510e524379a4dea34572f4c9) --- .../posthog-python-references-7.74.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.74.0.json diff --git a/references/posthog-python-references-7.74.0.json b/references/posthog-python-references-7.74.0.json new file mode 100644 index 000000000..2053aac41 --- /dev/null +++ b/references/posthog-python-references-7.74.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.74.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 973a24408..2053aac41 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.73.3", + "version": "7.74.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 300ea3fa1c033015c98bfde3fd3ab8ab0aa15152 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Wed, 21 Oct 2026 16:02:08 +0100 Subject: [PATCH 44/70] feat(django): add request context to OpenTelemetry spans (#1070) * feat(django): add request context to OpenTelemetry spans Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * fix(tracing): preserve span attributes and active context values Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * chore: use current tracing header settings in span checks Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * fix(tracing): respect disabled context owners Generated-By: PostHog Desktop Task-Id: bfd18848-e498-4352-a58a-b9ba85de4198 (cherry picked from commit 5f01fe93b893944f9b04c9e0f0536df46810143f) --- .sampo/changesets/django-otel-span-context.md | 5 + posthog/client.py | 6 +- posthog/contexts.py | 21 +- posthog/integrations/django.py | 3 + posthog/integrations/otel.py | 30 ++ .../test/integrations/test_otel_context.py | 423 ++++++++++++++++++ posthog/tracing/_context.py | 66 +++ references/middleware_configuration.md | 45 ++ references/public_api_snapshot.txt | 4 + 9 files changed, 597 insertions(+), 6 deletions(-) create mode 100644 .sampo/changesets/django-otel-span-context.md create mode 100644 posthog/integrations/otel.py create mode 100644 posthog/test/integrations/test_otel_context.py create mode 100644 posthog/tracing/_context.py diff --git a/.sampo/changesets/django-otel-span-context.md b/.sampo/changesets/django-otel-span-context.md new file mode 100644 index 000000000..90a517cd3 --- /dev/null +++ b/.sampo/changesets/django-otel-span-context.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: minor +--- + +Add an optional OpenTelemetry span processor for PostHog request IDs and enrich active Django request spans after request context is available. diff --git a/posthog/client.py b/posthog/client.py index 217478768..556029f53 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -50,6 +50,7 @@ from posthog.consumer import AI_MAX_MSG_SIZE, MAX_MSG_SIZE, Consumer, _DrainSignal from posthog.contexts import ( _get_current_context, + _get_active_span_context, get_capture_exception_code_variables_context, get_code_variables_detect_secrets_context, get_code_variables_ignore_patterns_context, @@ -2791,10 +2792,7 @@ def _traces_pipeline(self) -> Optional[PostHogTraces]: def _tracing_context(self) -> Dict[str, Optional[str]]: # The request context's identity, which the Django middleware fills # from the X-POSTHOG-* headers: the span's person/session join keys. - return { - "distinct_id": get_context_distinct_id(), - "session_id": get_context_session_id(), - } + return _get_active_span_context() def start_span( self, diff --git a/posthog/contexts.py b/posthog/contexts.py index a6af01635..1f9a00b8e 100644 --- a/posthog/contexts.py +++ b/posthog/contexts.py @@ -21,6 +21,7 @@ def __init__( ): self.client: Optional[Client] = client self._generation = _context_generation + self._span_context_active = True self.parent = parent self.fresh = fresh self.capture_exceptions = capture_exceptions @@ -167,6 +168,20 @@ def _get_current_context() -> Optional[ContextScope]: return current_context +def _get_active_span_context() -> Dict[str, Optional[str]]: + values: Dict[str, Optional[str]] = {"distinct_id": None, "session_id": None} + scope = _get_current_context() + while scope is not None and scope._span_context_active: + if values["distinct_id"] is None: + values["distinct_id"] = scope.distinct_id + if values["session_id"] is None: + values["session_id"] = scope.session_id + if scope.fresh: + break + scope = scope.parent + return values + + def _default_capture_exceptions(client: Optional["Client"] = None) -> bool: if client is not None: return client.enable_exception_autocapture @@ -203,8 +218,9 @@ def new_context( client: Optional client instance to use for capturing exceptions (default: None). If provided, the client will be used to capture exceptions within the context. If not provided, the default (global) client will be used. Note that the passed - client is only used to capture exceptions within the context - other events captured - within the context via `Client.capture` or `posthog.capture` will still carry the context + client controls exception capture and OpenTelemetry ID enrichment within the context. + Nested span enrichment keeps the nearest supplied client, including in fresh scopes. + Other events captured via `Client.capture` or `posthog.capture` still carry the context state (tags, identity, session id), but will be captured by the client directly used (or the global one, in the case of `posthog.capture`) @@ -256,6 +272,7 @@ def new_context( capture_exception(e) raise finally: + new_context._span_context_active = False if context_generation == _context_generation: _context_stack.set(new_context.get_parent()) diff --git a/posthog/integrations/django.py b/posthog/integrations/django.py index f241c6cb6..9c305a75c 100644 --- a/posthog/integrations/django.py +++ b/posthog/integrations/django.py @@ -2,6 +2,7 @@ from .. import contexts from ..client import Client +from ..tracing._context import _enrich_current_span from ..exception_utils import ( _ExceptionCaptureMetadata, _capture_exception_with_metadata, @@ -348,6 +349,7 @@ def __call__(self, request): for k, v in self.extract_tags(request).items(): contexts.tag(k, v) + _enrich_current_span() return self.get_response(request) async def __acall__(self, request): @@ -368,6 +370,7 @@ async def __acall__(self, request): for k, v in (await self.aextract_tags(request)).items(): contexts.tag(k, v) + _enrich_current_span() return await self.get_response(request) def process_exception(self, request, exception): diff --git a/posthog/integrations/otel.py b/posthog/integrations/otel.py new file mode 100644 index 000000000..fec4b282c --- /dev/null +++ b/posthog/integrations/otel.py @@ -0,0 +1,30 @@ +from typing import Optional + +from opentelemetry.context import Context +from opentelemetry.sdk.trace import Span, SpanProcessor + +from ..tracing._context import _enrich_current_span, _enrich_span + +__all__ = ["PostHogContextSpanProcessor", "enrich_current_span"] + + +def enrich_current_span() -> None: + """Add request IDs to an existing recording span after request context is set. + + Explicit span attributes take precedence. Missing OpenTelemetry support and + context lookup failures do not interrupt request handling. + """ + _enrich_current_span() + + +class PostHogContextSpanProcessor(SpanProcessor): + """Add PostHog request IDs to application-owned OpenTelemetry SDK spans. + + Add this processor to the application's existing TracerProvider before + starting requests. It snapshots child span context at span start, without + changing exporters, sampling or providers. Request integrations must also + enrich an incoming span that started before request context was available. + """ + + def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None: + _enrich_span(span) diff --git a/posthog/test/integrations/test_otel_context.py b/posthog/test/integrations/test_otel_context.py new file mode 100644 index 000000000..a8aac9935 --- /dev/null +++ b/posthog/test/integrations/test_otel_context.py @@ -0,0 +1,423 @@ +import asyncio +from contextlib import nullcontext +from unittest.mock import patch + +import pytest +from django.test import override_settings +from opentelemetry.sdk.trace import SpanLimits, TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter + +from posthog import contexts +from posthog.integrations.django import PosthogContextMiddleware +from posthog.integrations.otel import PostHogContextSpanProcessor, enrich_current_span +from posthog.test.integrations.test_middleware import MockRequest +from posthog.test.tracing.test_client_traces import ( + make_client, + mock_session, + flush_and_capture, + spans_from, +) + + +@pytest.fixture +def tracing(monkeypatch): + monkeypatch.setattr("posthog.project_api_key", "phc_key") + exporter = InMemorySpanExporter() + provider = TracerProvider() + provider.add_span_processor(PostHogContextSpanProcessor()) + provider.add_span_processor(SimpleSpanProcessor(exporter)) + yield provider.get_tracer(__name__), exporter + provider.shutdown() + + +@pytest.fixture +def native_client(): + client = make_client(traces={}) + with patch("posthog.tracing._transport._get_session", return_value=mock_session()): + yield client + client.shutdown() + + +@pytest.mark.parametrize( + "attributes,expected", + [ + ({}, {"sessionId": "session", "posthogDistinctId": "person"}), + ( + {"sessionId": "own-session", "posthogDistinctId": "own-person"}, + {"sessionId": "own-session", "posthogDistinctId": "own-person"}, + ), + ( + {"user.id": "authenticated"}, + {"user.id": "authenticated", "sessionId": "session"}, + ), + ], +) +def test_child_span_snapshots_context_and_preserves_identity( + tracing, attributes, expected +): + tracer, exporter = tracing + with contexts.new_context(fresh=True, capture_exceptions=False): + contexts.identify_context("person") + contexts.set_context_session("session") + span = tracer.start_span("child", attributes=attributes) + contexts.identify_context("later-person") + contexts.set_context_session("later-session") + span.end() + assert dict(exporter.get_finished_spans()[0].attributes) == expected + + +@pytest.mark.parametrize("disabled", [False, True]) +@pytest.mark.parametrize( + "owner", + ["scope", "inherited", "fresh", "global-client", "global-setting", "global-no-key"], +) +def test_enrichment_respects_owning_client_disabled_state( + tracing, monkeypatch, owner, disabled +): + tracer, exporter = tracing + client = make_client(send=False, disabled=disabled) + monkeypatch.setattr( + "posthog.default_client", client if owner == "global-client" else None + ) + monkeypatch.setattr( + "posthog.disabled", + disabled + if owner in {"global-setting", "global-no-key"} + else owner in {"scope", "inherited", "fresh"} and not disabled, + ) + monkeypatch.setattr("posthog.api_key", None) + monkeypatch.setattr( + "posthog.project_api_key", "phc_key" if owner == "global-setting" else " " + ) + disabled = disabled or owner == "global-no-key" + try: + with contexts.new_context( + fresh=True, + capture_exceptions=False, + client=client if owner in {"scope", "inherited", "fresh"} else None, + ): + nested = ( + contexts.new_context(fresh=owner == "fresh", capture_exceptions=False) + if owner in {"inherited", "fresh"} + else nullcontext() + ) + with ( + nested, + tracer.start_as_current_span( + "request", attributes={"posthogDistinctId": "application-person"} + ), + ): + contexts.identify_context("person") + contexts.set_context_session("session") + enrich_current_span() + tracer.start_span("child", attributes={"app.key": "keep"}).end() + finally: + client.shutdown() + spans = {span.name: dict(span.attributes) for span in exporter.get_finished_spans()} + assert spans["request"] == {"posthogDistinctId": "application-person"} | ( + {} if disabled else {"sessionId": "session"} + ) + assert spans["child"] == {"app.key": "keep"} | ( + {} if disabled else {"posthogDistinctId": "person", "sessionId": "session"} + ) + + +@pytest.mark.parametrize("outer_disabled", [False, True]) +def test_explicit_client_owns_fresh_nested_enrichment( + tracing, monkeypatch, outer_disabled +): + tracer, exporter = tracing + outer = make_client(send=False, disabled=outer_disabled) + inner = make_client(send=False, disabled=not outer_disabled) + monkeypatch.setattr("posthog.default_client", outer) + monkeypatch.setattr("posthog.disabled", outer_disabled) + try: + with contexts.new_context(fresh=True, client=outer, capture_exceptions=False): + contexts.identify_context("outer-person") + with contexts.new_context( + fresh=True, client=inner, capture_exceptions=False + ): + contexts.identify_context("inner-person") + contexts.set_context_session("inner-session") + tracer.start_span("child").end() + finally: + inner.shutdown() + outer.shutdown() + assert dict(exporter.get_finished_spans()[0].attributes) == ( + {"posthogDistinctId": "inner-person", "sessionId": "inner-session"} + if outer_disabled + else {} + ) + + +@pytest.mark.parametrize("initially_disabled", [False, True]) +def test_enrichment_observes_runtime_disabled_changes(tracing, initially_disabled): + tracer, exporter = tracing + client = make_client(send=False, disabled=initially_disabled) + try: + with contexts.new_context(fresh=True, client=client, capture_exceptions=False): + contexts.identify_context("person") + contexts.set_context_session("session") + before = tracer.start_span("before") + client.disabled = True + with tracer.start_as_current_span( + "disabled", attributes={"sessionId": "application-session"} + ): + enrich_current_span() + tracer.start_span("disabled-child").end() + client.disabled = False + tracer.start_span("enabled").end() + before.end() + finally: + client.shutdown() + spans = {span.name: dict(span.attributes) for span in exporter.get_finished_spans()} + ids = {"posthogDistinctId": "person", "sessionId": "session"} + assert spans["before"] == ({} if initially_disabled else ids) + assert spans["disabled"] == {"sessionId": "application-session"} + assert spans["disabled-child"] == {} + assert spans["enabled"] == ids + + +@pytest.mark.parametrize("failure", [ImportError("optional"), RuntimeError("lookup")]) +def test_current_span_lookup_failure_does_not_escape(failure): + with patch("opentelemetry.trace.get_current_span", side_effect=failure): + enrich_current_span() + + +def test_no_context_omits_identifiers(tracing): + tracer, exporter = tracing + with contexts.new_context(fresh=True, capture_exceptions=False): + tracer.start_span("unlinked").end() + assert dict(exporter.get_finished_spans()[0].attributes) == {} + + +@pytest.mark.parametrize("asynchronous", [False, True]) +@pytest.mark.parametrize("fail", [False, True]) +def test_django_enriches_existing_request_and_child_spans( + tracing, native_client, asynchronous, fail +): + tracer, exporter = tracing + + def view(request): + native_client.start_span("native").end() + tracer.start_span("child").end() + if fail: + raise ValueError("view failed") + return "response" + + async def async_view(request): + return view(request) + + async def run_async(middleware, request): + with tracer.start_as_current_span("request"): + return await middleware(request) + + request = MockRequest( + headers={ + "X-POSTHOG-DISTINCT-ID": "browser-person", + "X-POSTHOG-SESSION-ID": "browser-session", + } + ) + with ( + override_settings( + POSTHOG_MW_CAPTURE_EXCEPTIONS=False, POSTHOG_MW_CAPTURE_TRACING_HEADERS=True + ), + contexts.new_context(fresh=True, capture_exceptions=False), + ): + middleware = PosthogContextMiddleware(async_view if asynchronous else view) + with pytest.raises(ValueError) if fail else nullcontext(): + if asynchronous: + asyncio.run(run_async(middleware, request)) + else: + with tracer.start_as_current_span("request"): + middleware(request) + assert contexts.get_context_distinct_id() is None + assert contexts.get_context_session_id() is None + tracer.start_span("after-request").end() + spans = {span.name: span for span in exporter.get_finished_spans()} + for name in ("request", "child"): + assert dict(spans[name].attributes) == { + "posthogDistinctId": "browser-person", + "sessionId": "browser-session", + } + assert dict(spans["after-request"].attributes) == {} + payload, _, _ = flush_and_capture(native_client) + (native,) = spans_from(payload) + assert { + attribute["key"]: attribute["value"]["stringValue"] + for attribute in native["attributes"] + } == { + "posthogDistinctId": "browser-person", + "sessionId": "browser-session", + } + + +def test_async_django_requests_keep_separate_span_context(tracing): + tracer, exporter = tracing + both_started = asyncio.Event() + started = 0 + + async def view(request): + nonlocal started + started += 1 + if started == 2: + both_started.set() + await both_started.wait() + tracer.start_span(request.path + "-child").end() + return "response" + + async def run_request(middleware, identity): + request = MockRequest( + path=identity, + headers={ + "X-POSTHOG-DISTINCT-ID": identity, + "X-POSTHOG-SESSION-ID": identity + "-session", + }, + ) + with tracer.start_as_current_span(identity): + await middleware(request) + + async def run(): + await asyncio.gather( + *(run_request(middleware, identity) for identity in ("one", "two")) + ) + + with override_settings( + POSTHOG_MW_CAPTURE_EXCEPTIONS=False, POSTHOG_MW_CAPTURE_TRACING_HEADERS=True + ): + middleware = PosthogContextMiddleware(view) + asyncio.run(run()) + for span in exporter.get_finished_spans(): + identity = span.name.split("-")[0] + assert dict(span.attributes) == { + "posthogDistinctId": identity, + "sessionId": identity + "-session", + } + + +def test_context_lookup_failure_does_not_break_span_creation(tracing): + tracer, exporter = tracing + with patch.object( + contexts, "_get_active_span_context", side_effect=RuntimeError("context") + ): + tracer.start_span("child").end() + assert len(exporter.get_finished_spans()) == 1 + assert dict(exporter.get_finished_spans()[0].attributes) == {} + + +@pytest.mark.parametrize("nested", [False, True]) +@pytest.mark.parametrize( + "own_ids", + [ + {}, + {"distinct_id": "background-person"}, + {"session_id": "background-session"}, + {"distinct_id": "background-person", "session_id": "background-session"}, + ], +) +def test_spans_started_after_django_request_do_not_use_inherited_ids( + tracing, native_client, nested, own_ids +): + tracer, exporter = tracing + + async def run(): + release = asyncio.Event() + tasks = [] + + async def late_work(held, native_held): + await release.wait() + with contexts.new_context() if nested else nullcontext(): + if "distinct_id" in own_ids: + contexts.identify_context(own_ids["distinct_id"]) + if "session_id" in own_ids: + contexts.set_context_session(own_ids["session_id"]) + tracer.start_span("late").end() + native_client.start_span("native-late").end() + assert contexts.get_context_session_id() == own_ids.get( + "session_id", "session" + ) + held.end() + native_held.end() + + async def view(request): + tasks.append( + asyncio.create_task( + late_work( + tracer.start_span("held"), + native_client.start_span("native-held"), + ) + ) + ) + return "response" + + middleware = PosthogContextMiddleware(view) + await middleware( + MockRequest( + headers={ + "X-POSTHOG-DISTINCT-ID": "person", + "X-POSTHOG-SESSION-ID": "session", + } + ) + ) + release.set() + await asyncio.gather(*tasks) + + with override_settings( + POSTHOG_MW_CAPTURE_EXCEPTIONS=False, POSTHOG_MW_CAPTURE_TRACING_HEADERS=True + ): + asyncio.run(run()) + spans = {span.name: dict(span.attributes) for span in exporter.get_finished_spans()} + expected = { + key: own_ids[field] + for field, key in ( + ("distinct_id", "posthogDistinctId"), + ("session_id", "sessionId"), + ) + if nested and field in own_ids + } + assert spans["late"] == expected + assert spans["held"] == {"sessionId": "session", "posthogDistinctId": "person"} + payload, _, _ = flush_and_capture(native_client) + native = {span["name"]: span for span in spans_from(payload)} + assert { + attribute["key"]: attribute["value"]["stringValue"] + for attribute in native["native-late"].get("attributes", []) + } == expected + assert { + attribute["key"]: attribute["value"]["stringValue"] + for attribute in native["native-held"]["attributes"] + } == { + "sessionId": "session", + "posthogDistinctId": "person", + } + + +@pytest.mark.parametrize("limit", [0, 1, 2, 3, 128]) +@pytest.mark.parametrize("current_span", [False, True]) +def test_enrichment_does_not_evict_application_attributes( + monkeypatch, limit, current_span +): + monkeypatch.setattr("posthog.project_api_key", "phc_key") + provider = TracerProvider(span_limits=SpanLimits(max_span_attributes=limit)) + provider.add_span_processor(PostHogContextSpanProcessor()) + tracer = provider.get_tracer(__name__) + attributes = {"posthogDistinctId": "application-person", "other": "keep"} + baseline = tracer.start_span("baseline", attributes=attributes) + baseline.end() + try: + with contexts.new_context(fresh=True, capture_exceptions=False): + if not current_span: + contexts.set_context_session("session") + with tracer.start_as_current_span("span", attributes=attributes) as span: + if current_span: + contexts.set_context_session("session") + enrich_current_span() + retained = dict(list(attributes.items())[-limit:]) if limit else {} + expected = retained | ( + {"sessionId": "session"} if limit > len(attributes) else {} + ) + assert dict(span.attributes) == expected + assert span.dropped_attributes == baseline.dropped_attributes + finally: + provider.shutdown() diff --git a/posthog/tracing/_context.py b/posthog/tracing/_context.py new file mode 100644 index 000000000..25c5299da --- /dev/null +++ b/posthog/tracing/_context.py @@ -0,0 +1,66 @@ +import logging +from collections.abc import Mapping + +from .. import contexts + +log = logging.getLogger("posthog") +_IDENTITY_ATTRIBUTES = ( + "posthogDistinctId", + "posthog.distinct_id", + "user.id", + "enduser.id", +) + + +def _enrichment_is_enabled() -> bool: + scope = contexts._get_current_context() + while scope is not None: + if scope.client is not None: + return not scope.client.disabled + scope = scope.parent + + from .. import api_key, default_client, disabled, project_api_key + + if disabled: + return False + if default_client is not None: + return not default_client.disabled + return bool((project_api_key or "").strip() or (api_key or "").strip()) + + +def _enrich_span(span: object) -> None: + try: + if not _enrichment_is_enabled() or not getattr(span, "is_recording")(): + return + attributes = getattr(span, "attributes", None) + if not isinstance(attributes, Mapping): + return + context = contexts._get_active_span_context() + extra = {} + session_id = context["session_id"] + distinct_id = context["distinct_id"] + if session_id and "sessionId" not in attributes: + extra["sessionId"] = session_id + if distinct_id and not any(key in attributes for key in _IDENTITY_ATTRIBUTES): + extra["posthogDistinctId"] = distinct_id + if not extra: + return + # The SDK exposes no public capacity getter and evicts old attributes + # when full. Skip enrichment if its private limit is unavailable. + limit = getattr(getattr(span, "_limits", None), "max_span_attributes", None) + if not isinstance(limit, int) or len(attributes) + len(extra) > limit: + return + getattr(span, "set_attributes")(extra) + except Exception: + log.debug("Failed to add PostHog context to span", exc_info=True) + + +def _enrich_current_span() -> None: + try: + from opentelemetry.trace import get_current_span + + _enrich_span(get_current_span()) + except ImportError: + pass + except Exception: + log.debug("Failed to read current OpenTelemetry span", exc_info=True) diff --git a/references/middleware_configuration.md b/references/middleware_configuration.md index 2a065adaa..70cc236e3 100644 --- a/references/middleware_configuration.md +++ b/references/middleware_configuration.md @@ -90,3 +90,48 @@ request scope it is restored. Background threads do not automatically inherit request context; async tasks follow Python's context-variable propagation rules. Flask isolates identity and request properties while retaining effective enclosing exception code-variable privacy controls. + +## OpenTelemetry spans + +Native PostHog spans read the active request IDs when `start_span` runs. +For application-owned OpenTelemetry spans, install `opentelemetry-sdk` and add +`PostHogContextSpanProcessor` to the application's existing `TracerProvider`: + +```python +from posthog.integrations.otel import PostHogContextSpanProcessor + +provider.add_span_processor(PostHogContextSpanProcessor()) +``` + +Register the processor before requests start. Keep the existing provider, +exporters, and sampler. The processor adds `sessionId` and `posthogDistinctId` +from the active PostHog context when each recording span starts. These values +stay on the span after the request ends. Explicit span attributes take precedence. +The bridge skips enrichment when there is not enough attribute capacity or the +SDK does not expose its limit. OpenTelemetry SDK 1.20.0 or later is supported. +An existing application identity, such as `user.id`, prevents fallback identity +from being added. Absent IDs are omitted. OpenTelemetry remains optional for +applications that do not use this integration. + +Django's `PosthogContextMiddleware` also adds IDs to the active OpenTelemetry SDK +request span after it reads the request context. This covers a request span that +starts before the PostHog middleware. Put the OpenTelemetry request middleware +outside the PostHog middleware. Put Django's authentication middleware before +PostHog if you want authenticated user identity. Both sync and async Django +request handlers use the same bridge. Tracing headers are captured by default. +Set `POSTHOG_MW_CAPTURE_TRACING_HEADERS = False` to disable extraction. These +headers remain untrusted analytics context. + +For a custom request integration, call `enrich_current_span()` from +`posthog.integrations.otel` once after setting the request IDs. This call handles +an already active recording SDK span. The processor handles spans started later +in the request. A context lookup failure does not interrupt the request. +No provider, exporter, trace, session ID, or recording is created by this bridge. + +The bridge does not propagate context into a separate process or a new thread. +Only spans started during the supported request lifetime inherit request IDs. +Spans started by an inherited async task after the request ends omit request IDs. +A background task can set its own IDs in a new `new_context()` scope. +Only IDs from active scopes are used. Set `fresh=True` to prevent inheritance +from any parent scope. +The AI OpenTelemetry processor is a separate integration with different attributes. diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index 7d4079051..91f67d92b 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -1284,6 +1284,7 @@ class posthog.integrations.asgi.PosthogASGIMiddleware(app: _ASGIApp, client: Opt class posthog.integrations.celery.PosthogCeleryIntegration(client: Optional[Client] = None, capture_exceptions: bool = True, capture_task_lifecycle_events: bool = True, propagate_context: bool = True, task_filter: Optional[Callable[[Optional[str], dict[str, Any]], bool]] = None) class posthog.integrations.django.PosthogContextMiddleware(get_response) class posthog.integrations.flask.PosthogFlaskIntegration(app: Optional[Flask] = None, *, client: Optional[Client] = None, capture_exceptions: Optional[bool] = None, request_filter: Optional[Callable[[Request], bool]] = None, extra_properties: Optional[Callable[[Request], Mapping[str, Any]]] = None, trust_tracing_headers: Optional[bool] = None, capture_tracing_headers: Optional[bool] = None) +class posthog.integrations.otel.PostHogContextSpanProcessor class posthog.mcp.McpAnalytics(key: Any) class posthog.mcp.asgi.PostHogMcpStatelessSessionMiddleware(app: Any) class posthog.mcp.constants.PostHogMCPAnalyticsEvent @@ -1493,6 +1494,7 @@ function posthog.identify_context(distinct_id: str) function posthog.integrations.django.markcoroutinefunction(func) function posthog.integrations.drf.create_exception_handler(handler: Optional[Callable[[Exception, Mapping[str, Any]], Any]] = None, *, client: Optional[Client] = None, capture_exceptions: Optional[bool] = None, capture_4xx: bool = False, exception_filter: Optional[Callable[[Exception, Any, Mapping[str, Any]], bool]] = None) -> Callable[[Exception, Mapping[str, Any]], Any] function posthog.integrations.drf.exception_handler(exc: Exception, context: Mapping[str, Any]) -> Any +function posthog.integrations.otel.enrich_current_span() -> None function posthog.join() -> None function posthog.load_feature_flags() function posthog.mcp.asgi.autowire_stateless_mint(server: Any) -> None @@ -1804,6 +1806,7 @@ method posthog.integrations.django.PosthogContextMiddleware.extract_request_user method posthog.integrations.django.PosthogContextMiddleware.extract_tags(request) method posthog.integrations.django.PosthogContextMiddleware.process_exception(request, exception) method posthog.integrations.flask.PosthogFlaskIntegration.init_app(app: Flask) -> None +method posthog.integrations.otel.PostHogContextSpanProcessor.on_start(span: Span, parent_context: Optional[Context] = None) -> None method posthog.mcp.McpAnalytics.capture(event: str, properties: Optional[dict] = None) -> None method posthog.mcp.McpAnalytics.flush() -> None method posthog.mcp.posthog_mcp.PostHogMCP.capture(event: str, **kwargs: Unpack[OptionalCaptureArgs]) -> Optional[str] @@ -1916,6 +1919,7 @@ module posthog.integrations.celery module posthog.integrations.django module posthog.integrations.drf module posthog.integrations.flask +module posthog.integrations.otel module posthog.mcp module posthog.mcp.asgi module posthog.mcp.constants From e02c274bb02a1d6edc650a169f614bf57443ab86 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Wed, 21 Oct 2026 16:02:09 +0100 Subject: [PATCH 45/70] fix: enrich Flask, ASGI, and Celery spans with context (#1075) * fix(flask): add request context to active OpenTelemetry spans Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * fix(asgi): enrich active request spans Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * fix(celery): enrich active task spans with job context Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * chore: use current tracing header settings in framework checks Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * fix(celery): preserve caller span identity during eager tasks Generated-By: PostHog Desktop Task-Id: 5681be44-4986-48db-b140-1bda88f75f96 * chore(tests): use enabled clients in span tests Generated-By: PostHog Desktop Task-Id: bfd18848-e498-4352-a58a-b9ba85de4198 (cherry picked from commit 5ddb4464a634a1dddf9b585cb9cf804c671a2edf) --- .sampo/changesets/asgi-otel-span-context.md | 5 + .sampo/changesets/celery-otel-span-context.md | 5 + .sampo/changesets/flask-otel-span-context.md | 5 + posthog/integrations/asgi.py | 3 + posthog/integrations/celery.py | 20 ++ posthog/integrations/flask.py | 3 + .../integrations/test_asgi_otel_context.py | 247 +++++++++++++++ .../integrations/test_celery_otel_context.py | 238 ++++++++++++++ posthog/test/integrations/test_flask_spans.py | 177 +++++++++++ pyproject.toml | 3 + references/middleware_configuration.md | 60 ++++ uv.lock | 295 +++++++++++++++++- 12 files changed, 1060 insertions(+), 1 deletion(-) create mode 100644 .sampo/changesets/asgi-otel-span-context.md create mode 100644 .sampo/changesets/celery-otel-span-context.md create mode 100644 .sampo/changesets/flask-otel-span-context.md create mode 100644 posthog/test/integrations/test_asgi_otel_context.py create mode 100644 posthog/test/integrations/test_celery_otel_context.py create mode 100644 posthog/test/integrations/test_flask_spans.py diff --git a/.sampo/changesets/asgi-otel-span-context.md b/.sampo/changesets/asgi-otel-span-context.md new file mode 100644 index 000000000..a3d821ea2 --- /dev/null +++ b/.sampo/changesets/asgi-otel-span-context.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Add active PostHog request IDs to existing OpenTelemetry spans in ASGI middleware. diff --git a/.sampo/changesets/celery-otel-span-context.md b/.sampo/changesets/celery-otel-span-context.md new file mode 100644 index 000000000..0cb6c9285 --- /dev/null +++ b/.sampo/changesets/celery-otel-span-context.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Add propagated task context to active Celery OpenTelemetry spans. diff --git a/.sampo/changesets/flask-otel-span-context.md b/.sampo/changesets/flask-otel-span-context.md new file mode 100644 index 000000000..fc475163a --- /dev/null +++ b/.sampo/changesets/flask-otel-span-context.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Add available PostHog request IDs to active Flask OpenTelemetry request spans. diff --git a/posthog/integrations/asgi.py b/posthog/integrations/asgi.py index 5d381c4c0..d58f818db 100644 --- a/posthog/integrations/asgi.py +++ b/posthog/integrations/asgi.py @@ -34,6 +34,7 @@ from .. import contexts from ..client import Client +from ..tracing._context import _enrich_current_span from ..exception_utils import ( _ExceptionCaptureMetadata, _capture_exception_with_metadata, @@ -249,6 +250,8 @@ async def __call__(self, scope, receive, send) -> None: self.capture_tracing_headers, ) + _enrich_current_span() + properties = _extract_properties(scope, headers) if self.extra_properties: extra_properties = await _resolve_callback_result( diff --git a/posthog/integrations/celery.py b/posthog/integrations/celery.py index 59a513be4..c11117922 100644 --- a/posthog/integrations/celery.py +++ b/posthog/integrations/celery.py @@ -67,6 +67,7 @@ import json import logging import time +from collections.abc import Mapping from typing import Any, Callable, Optional, cast from .. import contexts @@ -75,6 +76,7 @@ _ExceptionCaptureMetadata, _capture_exception_with_metadata, ) +from ..tracing._context import _enrich_span CONTEXT_DISTINCT_ID_HEADER = "X-POSTHOG-DISTINCT-ID" @@ -309,6 +311,7 @@ def _on_task_prerun(self, *args, **kwargs): request._posthog_start = time.monotonic() self._apply_propagated_identity(request) + self._enrich_task_span(task_id) merged_tags = {**task_properties, **context_tags} for key, value in merged_tags.items(): @@ -326,6 +329,23 @@ def _on_task_prerun(self, *args, **kwargs): except Exception: pass + @staticmethod + def _enrich_task_span(task_id: str) -> None: + try: + from opentelemetry.trace import get_current_span + + span = get_current_span() + attributes = getattr(span, "attributes", None) + if ( + isinstance(attributes, Mapping) + and attributes.get("celery.task_id") == task_id + ): + _enrich_span(span) + except ImportError: + pass + except Exception: + logger.debug("Failed to read current Celery task span", exc_info=True) + def _on_task_success(self, *args, **kwargs): self._handle_task_end("success", **kwargs) diff --git a/posthog/integrations/flask.py b/posthog/integrations/flask.py index 8c416e5dc..345c37419 100644 --- a/posthog/integrations/flask.py +++ b/posthog/integrations/flask.py @@ -25,6 +25,7 @@ from .. import contexts from ..client import Client +from ..tracing._context import _enrich_current_span from ..exception_utils import ( _ExceptionCaptureMetadata, _capture_exception_with_metadata, @@ -201,6 +202,8 @@ def _before_request(self) -> None: for key, value in extra_properties.items(): contexts.tag(key, value) + _enrich_current_span() + @staticmethod def _request_properties(request: Request) -> dict[str, Any]: properties: dict[str, Any] = { diff --git a/posthog/test/integrations/test_asgi_otel_context.py b/posthog/test/integrations/test_asgi_otel_context.py new file mode 100644 index 000000000..2739eb830 --- /dev/null +++ b/posthog/test/integrations/test_asgi_otel_context.py @@ -0,0 +1,247 @@ +import asyncio +from contextlib import nullcontext +from unittest.mock import patch + +import pytest +from fastapi import FastAPI +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter + +from posthog import contexts +from posthog.integrations.asgi import PosthogASGIMiddleware +from posthog.integrations.otel import PostHogContextSpanProcessor +from posthog.test.integrations.test_asgi_integration import ( + http_scope, + noop_receive, + noop_send, +) +from posthog.test.tracing.test_client_traces import ( + flush_and_capture, + make_client, + mock_session, + spans_from, +) + + +@pytest.fixture +def tracing(monkeypatch): + monkeypatch.setattr("posthog.project_api_key", "phc_key") + exporter = InMemorySpanExporter() + provider = TracerProvider() + provider.add_span_processor(PostHogContextSpanProcessor()) + provider.add_span_processor(SimpleSpanProcessor(exporter)) + yield provider.get_tracer(__name__), exporter + provider.shutdown() + + +@pytest.mark.parametrize("scope_type", ["http", "websocket"]) +@pytest.mark.parametrize( + "trust,headers,attributes,fail,expected", + [ + ( + True, + None, + {}, + False, + {"sessionId": "session-123", "posthogDistinctId": "user-456"}, + ), + ( + True, + None, + {}, + True, + {"sessionId": "session-123", "posthogDistinctId": "user-456"}, + ), + (False, None, {}, False, {}), + (True, [], {}, False, {}), + ( + True, + [(b"x-posthog-session-id", b"\x00\n"), (b"x-posthog-distinct-id", b"\t ")], + {}, + False, + {}, + ), + ( + True, + None, + {"user.id": "authenticated"}, + False, + {"user.id": "authenticated", "sessionId": "session-123"}, + ), + ( + True, + None, + {"sessionId": "explicit-session", "posthogDistinctId": "explicit-person"}, + False, + {"sessionId": "explicit-session", "posthogDistinctId": "explicit-person"}, + ), + ], +) +async def test_asgi_enriches_existing_request_and_child_spans( + tracing, scope_type, trust, headers, attributes, fail, expected +): + tracer, exporter = tracing + + async def app(scope, receive, send): + tracer.start_span("child", attributes=attributes).end() + if fail: + raise ValueError("handler failed") + await send( + {"type": "websocket.close"} + if scope_type == "websocket" + else {"type": "http.response.body", "body": b""} + ) + + scope = http_scope(type=scope_type) + if headers is not None: + scope["headers"] = headers + middleware = PosthogASGIMiddleware( + app, capture_exceptions=False, capture_tracing_headers=trust + ) + with contexts.new_context(fresh=True, capture_exceptions=False): + with ( + pytest.raises(ValueError, match="handler failed") if fail else nullcontext() + ): + with tracer.start_as_current_span("request", attributes=attributes): + await middleware(scope, noop_receive, noop_send) + assert contexts.get_context_session_id() is None + assert contexts.get_context_distinct_id() is None + tracer.start_span("after-request").end() + + spans = {span.name: span for span in exporter.get_finished_spans()} + for name in ("request", "child"): + assert dict(spans[name].attributes) == expected + assert dict(spans["after-request"].attributes) == {} + + +async def test_asgi_concurrent_requests_and_ended_task_context(tracing): + tracer, exporter = tracing + both_started = asyncio.Event() + finished = asyncio.Event() + held_spans = [] + background_tasks = [] + + async def background(name): + await finished.wait() + tracer.start_span("late-" + name).end() + + async def app(scope, receive, send): + name = scope["path"] + held_spans.append(tracer.start_span("held-" + name)) + background_tasks.append(asyncio.create_task(background(name))) + if len(held_spans) == 2: + both_started.set() + await both_started.wait() + tracer.start_span("child-" + name).end() + + middleware = PosthogASGIMiddleware(app, capture_tracing_headers=True) + + async def request(name): + with tracer.start_as_current_span("request-" + name): + await middleware( + http_scope( + path=name, + headers=[ + (b"x-posthog-session-id", ("session-" + name).encode()), + (b"x-posthog-distinct-id", ("person-" + name).encode()), + ], + ), + noop_receive, + noop_send, + ) + + with contexts.new_context(fresh=True, capture_exceptions=False): + await asyncio.gather(request("first"), request("second")) + finished.set() + await asyncio.gather(*background_tasks) + for span in held_spans: + span.end() + + spans = {span.name: span for span in exporter.get_finished_spans()} + for name in ("first", "second"): + for prefix in ("request-", "child-", "held-"): + assert dict(spans[prefix + name].attributes) == { + "sessionId": "session-" + name, + "posthogDistinctId": "person-" + name, + } + assert dict(spans["late-" + name].attributes) == {} + + +@pytest.mark.parametrize("scope_type,filtered", [("http", True), ("lifespan", False)]) +async def test_asgi_bypassed_scopes_do_not_enrich_spans(tracing, scope_type, filtered): + tracer, exporter = tracing + + async def app(scope, receive, send): + tracer.start_span("child").end() + + middleware = PosthogASGIMiddleware( + app, + capture_tracing_headers=True, + request_filter=(lambda scope: False) if filtered else None, + ) + with contexts.new_context(fresh=True, capture_exceptions=False): + with tracer.start_as_current_span("request"): + await middleware(http_scope(type=scope_type), noop_receive, noop_send) + assert all(dict(span.attributes) == {} for span in exporter.get_finished_spans()) + + +@pytest.mark.parametrize("asynchronous", [False, True]) +@pytest.mark.parametrize("fail", [False, True]) +async def test_fastapi_sync_and_async_handlers_enrich_native_and_otel_spans( + tracing, asynchronous, fail +): + tracer, exporter = tracing + native = make_client(traces={}) + + def handler(): + native.start_span("native").end() + tracer.start_span("child").end() + if fail: + raise ValueError("handler failed") + return {"ok": True} + + async def async_handler(): + return handler() + + app = FastAPI() + app.add_api_route("/api/items", async_handler if asynchronous else handler) + app.add_middleware( + PosthogASGIMiddleware, capture_tracing_headers=True, capture_exceptions=False + ) + responses = [] + + async def send(message): + responses.append(message) + + try: + with ( + patch( + "posthog.tracing._transport._get_session", return_value=mock_session() + ), + contexts.new_context(fresh=True, capture_exceptions=False), + ): + with ( + pytest.raises(ValueError, match="handler failed") + if fail + else nullcontext() + ): + with tracer.start_as_current_span("request"): + await app(http_scope(), noop_receive, send) + assert contexts.get_context_session_id() is None + assert contexts.get_context_distinct_id() is None + payload, _, _ = flush_and_capture(native) + finally: + native.shutdown() + + assert responses[0]["status"] == (500 if fail else 200) + spans = {span.name: span for span in exporter.get_finished_spans()} + for name in ("request", "child"): + assert dict(spans[name].attributes) == { + "sessionId": "session-123", + "posthogDistinctId": "user-456", + } + [span] = spans_from(payload) + attributes = {item["key"]: item["value"] for item in span["attributes"]} + assert attributes["sessionId"] == {"stringValue": "session-123"} + assert attributes["posthogDistinctId"] == {"stringValue": "user-456"} diff --git a/posthog/test/integrations/test_celery_otel_context.py b/posthog/test/integrations/test_celery_otel_context.py new file mode 100644 index 000000000..678722cd4 --- /dev/null +++ b/posthog/test/integrations/test_celery_otel_context.py @@ -0,0 +1,238 @@ +from unittest.mock import Mock + +import pytest +from celery import Celery +from opentelemetry import trace +from opentelemetry.instrumentation.celery import CeleryInstrumentor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter + +from posthog import contexts +from posthog.integrations.celery import ( + CONTEXT_DISTINCT_ID_HEADER, + CONTEXT_SESSION_ID_HEADER, + PosthogCeleryIntegration, +) +from posthog.integrations.otel import PostHogContextSpanProcessor + + +@pytest.fixture +def celery_tracing(): + app = Celery("span-context", broker="memory://") + integration = PosthogCeleryIntegration( + client=Mock(disabled=False), + capture_exceptions=False, + capture_task_lifecycle_events=False, + ) + exporter = InMemorySpanExporter() + provider = TracerProvider() + provider.add_span_processor(PostHogContextSpanProcessor()) + provider.add_span_processor(SimpleSpanProcessor(exporter)) + integration.instrument() + try: + yield app, provider.get_tracer(__name__), exporter, provider + finally: + integration.shutdown() + provider.shutdown() + app.close() + + +@pytest.mark.parametrize("state", ["success", "failure", "retry"]) +@pytest.mark.parametrize("propagated", [True, False]) +def test_eager_task_enriches_existing_span_and_clears_context( + celery_tracing, state, propagated +): + app, tracer, exporter, _ = celery_tracing + headers = ( + { + CONTEXT_DISTINCT_ID_HEADER: "job-person", + CONTEXT_SESSION_ID_HEADER: "job-session", + } + if propagated + else {} + ) + expected = ( + {"posthogDistinctId": "job-person", "sessionId": "job-session"} + if propagated + else {} + ) + attempts = [] + + @app.task(bind=True, name="span-context.task") + def task(self): + attempts.append(self.request.retries) + tracer.start_span("child").end() + assert contexts.get_context_distinct_id() == ( + "job-person" if propagated else None + ) + assert contexts.get_context_session_id() == ( + "job-session" if propagated else None + ) + if state == "failure": + raise ValueError("task failed") + if state == "retry" and self.request.retries == 0: + raise self.retry(exc=ValueError("try again"), countdown=0) + return "done" + + task_id = "owned-task" + task_span = tracer.start_span("task", attributes={"celery.task_id": task_id}) + with ( + trace.use_span(task_span, end_on_exit=True), + contexts.new_context(fresh=True, capture_exceptions=False), + ): + contexts.identify_context("outer-person") + contexts.set_context_session("outer-session") + result = task.apply(task_id=task_id, headers=headers, throw=False) + assert result.state == ("FAILURE" if state == "failure" else "SUCCESS") + assert contexts.get_context_distinct_id() == "outer-person" + assert contexts.get_context_session_id() == "outer-session" + + assert attempts == ([0, 1] if state == "retry" else [0]) + tracer.start_span("after-task").end() + for span in exporter.get_finished_spans(): + span_expected = {} if span.name == "after-task" else expected + if span.name == "task": + span_expected = {**span_expected, "celery.task_id": task_id} + assert dict(span.attributes) == span_expected + + +def test_published_context_reaches_task_span_without_worker_context_bleed( + celery_tracing, +): + app, tracer, exporter, _ = celery_tracing + + @app.task(name="span-context.published") + def task(): + tracer.start_span("child").end() + return contexts.get_context_distinct_id(), contexts.get_context_session_id() + + with contexts.new_context(fresh=True, capture_exceptions=False): + contexts.identify_context("producer-person") + contexts.set_context_session("producer-session") + task.apply_async() + + with app.connection_for_read() as connection: + with connection.SimpleQueue("celery") as queue: + message = queue.get(block=False) + worker_headers = message.headers["headers"] + message.ack() + + with tracer.start_as_current_span( + "task", attributes={"celery.task_id": "published"} + ): + result = task.apply(task_id="published", headers=worker_headers) + assert result.get() == ("producer-person", "producer-session") + + with tracer.start_as_current_span( + "unlinked-task", attributes={"celery.task_id": "unlinked"} + ): + assert task.apply(task_id="unlinked").get() == (None, None) + expected = { + "posthogDistinctId": "producer-person", + "sessionId": "producer-session", + } + spans = exporter.get_finished_spans() + assert [dict(span.attributes) for span in spans] == [ + expected, + {**expected, "celery.task_id": "published"}, + {}, + {"celery.task_id": "unlinked"}, + ] + + +@pytest.mark.parametrize("state", ["success", "failure", "retry"]) +def test_official_eager_task_spans_do_not_stamp_the_caller(celery_tracing, state): + app, tracer, exporter, provider = celery_tracing + instrumentor = CeleryInstrumentor() + instrumentor.instrument(tracer_provider=provider) + + @app.task(bind=True, name="span-context.official") + def task(self): + tracer.start_span(f"child-{self.request.id}").end() + if state == "failure": + raise ValueError("task failed") + if state == "retry" and self.request.retries == 0: + raise self.retry(exc=ValueError("try again"), countdown=0) + return "done" + + try: + with tracer.start_as_current_span("caller") as caller: + for name in ("first", "second"): + result = task.apply( + task_id=name, + headers={ + CONTEXT_DISTINCT_ID_HEADER: f"{name}-person", + CONTEXT_SESSION_ID_HEADER: f"{name}-session", + }, + throw=False, + ) + assert result.state == ("FAILURE" if state == "failure" else "SUCCESS") + assert dict(caller.attributes) == {} + assert contexts.get_context_distinct_id() is None + assert contexts.get_context_session_id() is None + tracer.start_span("after-tasks").end() + finally: + instrumentor.uninstrument() + + task_spans = [ + span + for span in exporter.get_finished_spans() + if span.kind == trace.SpanKind.CONSUMER + ] + assert len(task_spans) == (4 if state == "retry" else 2) + for span in exporter.get_finished_spans(): + if span.name in ("caller", "after-tasks"): + assert dict(span.attributes) == {} + else: + name = ( + span.name.removeprefix("child-") + if span.name.startswith("child-") + else span.attributes["messaging.message.id"] + ) + assert span.attributes["posthogDistinctId"] == f"{name}-person" + assert span.attributes["sessionId"] == f"{name}-session" + + +@pytest.mark.parametrize( + "attributes", [{}, {"celery.task_id": "other-task"}, {"celery.task_id": 42}] +) +def test_eager_task_does_not_enrich_an_unverified_span(celery_tracing, attributes): + app, tracer, exporter, _ = celery_tracing + + @app.task(name="span-context.unverified") + def task(): + tracer.start_span("child").end() + + with tracer.start_as_current_span("task", attributes=attributes): + task.apply( + task_id="actual-task", headers={CONTEXT_SESSION_ID_HEADER: "job-session"} + ) + child, parent = exporter.get_finished_spans() + assert dict(child.attributes) == {"sessionId": "job-session"} + assert dict(parent.attributes) == attributes + + +@pytest.mark.parametrize("api_state", ["missing", "failing", "unreadable"]) +def test_task_context_survives_unavailable_current_span_api( + celery_tracing, monkeypatch, api_state +): + app, _, _, _ = celery_tracing + if api_state == "missing": + monkeypatch.delattr(trace, "get_current_span") + elif api_state == "failing": + monkeypatch.setattr( + trace, "get_current_span", Mock(side_effect=RuntimeError("lookup failed")) + ) + else: + monkeypatch.setattr(trace, "get_current_span", lambda: object()) + + @app.task(name="span-context.unavailable") + def task(): + return contexts.get_context_session_id() + + assert ( + task.apply(headers={CONTEXT_SESSION_ID_HEADER: "job-session"}).get() + == "job-session" + ) + assert contexts.get_context_session_id() is None diff --git a/posthog/test/integrations/test_flask_spans.py b/posthog/test/integrations/test_flask_spans.py new file mode 100644 index 000000000..59de68d35 --- /dev/null +++ b/posthog/test/integrations/test_flask_spans.py @@ -0,0 +1,177 @@ +from concurrent.futures import ThreadPoolExecutor +from contextlib import nullcontext +from threading import Barrier +from unittest.mock import patch + +import pytest +from flask import Flask +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter + +from posthog import contexts +from posthog.integrations.flask import PosthogFlaskIntegration +from posthog.integrations.otel import PostHogContextSpanProcessor +from posthog.test.tracing.test_client_traces import ( + flush_and_capture, + make_client, + mock_session, + spans_from, +) + + +@pytest.fixture +def tracing(monkeypatch): + monkeypatch.setattr("posthog.project_api_key", "phc_key") + exporter = InMemorySpanExporter() + provider = TracerProvider() + provider.add_span_processor(PostHogContextSpanProcessor()) + provider.add_span_processor(SimpleSpanProcessor(exporter)) + yield provider.get_tracer(__name__), exporter + provider.shutdown() + + +@pytest.fixture +def native_client(): + client = make_client(traces={}) + with patch("posthog.tracing._transport._get_session", return_value=mock_session()): + yield client + client.shutdown() + + +@pytest.mark.parametrize("fail", [False, True]) +def test_flask_enriches_existing_request_and_child_spans_and_cleans_up( + tracing, native_client, fail +): + tracer, exporter = tracing + app = Flask(__name__) + app.config["TESTING"] = True + PosthogFlaskIntegration(app, capture_tracing_headers=True, capture_exceptions=False) + + @app.get("/") + def view(): + native_client.start_span("native").end() + tracer.start_span("child").end() + if fail: + raise ValueError("view failed") + return "response" + + with contexts.new_context(fresh=True, capture_exceptions=False): + with pytest.raises(ValueError, match="view failed") if fail else nullcontext(): + with tracer.start_as_current_span("request"): + response = app.test_client().get( + "/", + headers={ + "X-PostHog-Distinct-ID": "browser-person", + "X-PostHog-Session-ID": "browser-session", + }, + ) + assert response.status_code == 200 + tracer.start_span("after-request").end() + assert contexts.get_context_distinct_id() is None + assert contexts.get_context_session_id() is None + + spans = {span.name: dict(span.attributes) for span in exporter.get_finished_spans()} + expected = { + "posthogDistinctId": "browser-person", + "sessionId": "browser-session", + } + assert spans == {"request": expected, "child": expected, "after-request": {}} + payload, _, _ = flush_and_capture(native_client) + (native,) = spans_from(payload) + assert { + attribute["key"]: attribute["value"]["stringValue"] + for attribute in native["attributes"] + } == expected + + +@pytest.mark.parametrize( + "trust,headers,attributes,expected", + [ + ( + False, + {"X-PostHog-Distinct-ID": "person", "X-PostHog-Session-ID": "session"}, + {}, + {}, + ), + (True, {}, {}, {}), + (True, {"X-PostHog-Distinct-ID": " ", "X-PostHog-Session-ID": " "}, {}, {}), + (True, {"X-PostHog-Session-ID": "session"}, {}, {"sessionId": "session"}), + ( + True, + {"X-PostHog-Distinct-ID": "person"}, + {}, + {"posthogDistinctId": "person"}, + ), + ( + True, + {"X-PostHog-Distinct-ID": "person", "X-PostHog-Session-ID": "session"}, + {"posthogDistinctId": "own-person", "sessionId": "own-session"}, + {"posthogDistinctId": "own-person", "sessionId": "own-session"}, + ), + ( + True, + {"X-PostHog-Distinct-ID": "person", "X-PostHog-Session-ID": "session"}, + {"user.id": "authenticated"}, + {"user.id": "authenticated", "sessionId": "session"}, + ), + ], +) +def test_flask_request_span_respects_header_policy_and_explicit_identity( + tracing, trust, headers, attributes, expected +): + tracer, exporter = tracing + app = Flask(__name__) + PosthogFlaskIntegration( + app, capture_tracing_headers=trust, capture_exceptions=False + ) + app.add_url_rule("/", view_func=lambda: "response") + + with contexts.new_context(fresh=True, capture_exceptions=False): + with tracer.start_as_current_span("request", attributes=attributes): + assert app.test_client().get("/", headers=headers).status_code == 200 + + assert dict(exporter.get_finished_spans()[0].attributes) == expected + + +def test_flask_concurrent_requests_keep_separate_span_context(tracing): + tracer, exporter = tracing + app = Flask(__name__) + both_started = Barrier(2) + PosthogFlaskIntegration(app, capture_tracing_headers=True, capture_exceptions=False) + + @app.get("/") + def view(identity): + both_started.wait(timeout=5) + tracer.start_span(identity + "-child").end() + return "response" + + def run_request(identity): + with contexts.new_context(fresh=True, capture_exceptions=False): + with tracer.start_as_current_span(identity): + assert ( + app.test_client() + .get( + "/" + identity, + headers={ + "X-PostHog-Distinct-ID": identity, + "X-PostHog-Session-ID": identity + "-session", + }, + ) + .status_code + == 200 + ) + tracer.start_span(identity + "-after").end() + + with ThreadPoolExecutor(max_workers=2) as executor: + list(executor.map(run_request, ("first", "second"))) + + spans = {span.name: dict(span.attributes) for span in exporter.get_finished_spans()} + for identity in ("first", "second"): + expected = { + "posthogDistinctId": identity, + "sessionId": identity + "-session", + } + assert spans[identity] == expected + assert spans[identity + "-child"] == expected + assert spans[identity + "-after"] == {} diff --git a/pyproject.toml b/pyproject.toml index cc49bbaf5..c29f296c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,9 @@ dev = [ test = [ "freezegun==1.5.1", "flask>=2.2", + "celery>=5.3,<6", + "opentelemetry-instrumentation-celery>=0.41b0", + "fastapi>=0.115,<1", "python-dateutil>=2.9.0.post0", "tzdata", "coverage", diff --git a/references/middleware_configuration.md b/references/middleware_configuration.md index 70cc236e3..472d2dc94 100644 --- a/references/middleware_configuration.md +++ b/references/middleware_configuration.md @@ -122,6 +122,35 @@ request handlers use the same bridge. Tracing headers are captured by default. Set `POSTHOG_MW_CAPTURE_TRACING_HEADERS = False` to disable extraction. These headers remain untrusted analytics context. +Flask's `PosthogFlaskIntegration` adds IDs to the active OpenTelemetry SDK +request span after its request hook sets the context. Keep OpenTelemetry's WSGI +middleware outside the Flask app so that its request span is active before +Flask runs `before_request` hooks. Browser session and person headers are captured +by default. Set `capture_tracing_headers=False` to disable extraction. Register the shared processor above for +child spans; the request hook alone does not enrich later OpenTelemetry spans. +The application must set authenticated identity on the request span before the +PostHog hook if that identity must take precedence over a browser header. +Requests excluded by `request_filter` receive no enrichment. Flask request +context closes in `teardown_request`, including when the view raises an error. + +ASGI's `PosthogASGIMiddleware` also adds IDs after it reads the headers. This +covers an active recording request span started by outer tracing middleware. +FastAPI applications use the same ASGI middleware: + +```python +from posthog.integrations.asgi import PosthogASGIMiddleware + +app.add_middleware(PosthogASGIMiddleware) +``` + +Keep OpenTelemetry request tracing outside this middleware and register +`PostHogContextSpanProcessor` for child spans. Both async handlers and FastAPI's +sync handlers run within the request context. HTTP and WebSocket scopes are +supported; WebSocket tracing requires the application to supply a recording span. +Lifespan scopes and requests rejected by `request_filter` pass through without +span enrichment. The middleware does not create request spans. Spans started by +outer error-response handlers after the PostHog scope exits omit request IDs. + For a custom request integration, call `enrich_current_span()` from `posthog.integrations.otel` once after setting the request IDs. This call handles an already active recording SDK span. The processor handles spans started later @@ -135,3 +164,34 @@ A background task can set its own IDs in a new `new_context()` scope. Only IDs from active scopes are used. Set `fresh=True` to prevent inheritance from any parent scope. The AI OpenTelemetry processor is a separate integration with different attributes. + +## Celery task spans + +`PosthogCeleryIntegration` carries context through its existing task message +headers when `propagate_context=True` (the default). Instrument the producer and +each worker process. A worker starts a fresh PostHog context before each task and +restores the prior context after success, failure, or retry. A task without +PostHog headers does not inherit identity or session IDs from an enclosing scope. + +Add `PostHogContextSpanProcessor` to the application's existing provider for +child spans. The Celery integration also enriches an active task span after it +reads the message headers, but only when its public `celery.task_id` attribute +exactly matches the current task ID. Other active spans remain unchanged. +It does not create task spans. To create task spans, +install and configure `opentelemetry-instrumentation-celery` separately. + +Call `PosthogCeleryIntegration.instrument()` before +`CeleryInstrumentor().instrument(tracer_provider=provider)`. This order ensures +that PostHog restores the job context before OpenTelemetry starts the task span. +This also matters for eager and nested tasks: with the reverse order, the span +processor can read the enclosing context before the task context is available. +Existing span attributes are preserved, so the later task hook cannot replace +those values. Official Celery instrumentation does not expose a matching +`celery.task_id` at this hook. The later task hook therefore cannot repair task +spans created in the reverse order. + +Celery's eager execution does not emit task publish signals. To carry context +into an eager task, pass the task's PostHog headers explicitly with +`task.apply(headers=...)` or `task.apply_async(headers=...)`. Do not use these +analytics headers for authentication or authorization. Task context propagation +does not grant a background task access to an ended request scope. diff --git a/uv.lock b/uv.lock index 40ac6fc46..4fbfdc774 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -257,6 +257,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] +[[package]] +name = "amqp" +version = "5.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "vine" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/41/63526ffa542b7dbeb671ab2252fb38e26cd2dbc68c0775cdc5ba11af78a7/amqp-5.4.1.tar.gz", hash = "sha256:79a9c0ab70e71745667f127ff80666894a734c26236b6f33149c964b096f0b20", size = 132240, upload-time = "2026-10-05T14:03:23.415Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/8e/25f762f8cf0da76c7b1a66a9cadc291168537598c533954b0e2c9de3a0a3/amqp-5.4.1-py3-none-any.whl", hash = "sha256:ac2b816a14a380ed10c5ebbf85a334fd68111fa476496867a5ccd2fd09926d5e", size = 51858, upload-time = "2026-10-05T14:03:18.61Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -388,6 +409,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl", hash = "sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2", size = 1333658, upload-time = "2025-12-13T06:50:28.266Z" }, ] +[[package]] +name = "billiard" +version = "4.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/0d/8921e960be19fa226358bf933509f57ec679d9b35a1e7ea43460af4b7fef/billiard-4.3.1.tar.gz", hash = "sha256:c88559b306ee5dc93f8d5f843d07da15d795d67af26720d14ee9d09f09eb0b22", size = 166478, upload-time = "2026-10-05T06:38:30.496Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/b1/360936699597063a2d9863aa94ccc3a6951e906ced032a9a1d8e562fc56b/billiard-4.3.1-py3-none-any.whl", hash = "sha256:2c7075283191d9c0add66cf8fca8e06ba599e75fe7319b67186759f8877dfdaf", size = 90178, upload-time = "2026-10-05T06:38:28.373Z" }, +] + [[package]] name = "blinker" version = "1.9.0" @@ -435,6 +465,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/93/1f76c8d1bafe3b0614e06b2195784a3765bbf7b0a067661af9e2dd47fc33/caio-0.9.25-py3-none-any.whl", hash = "sha256:06c0bb02d6b929119b1cfbe1ca403c768b2013a369e2db46bfa2a5761cf82e40", size = 19087, upload-time = "2025-12-26T15:22:00.221Z" }, ] +[[package]] +name = "celery" +version = "5.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "billiard" }, + { name = "click" }, + { name = "click-didyoumean" }, + { name = "click-plugins" }, + { name = "click-repl" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "kombu" }, + { name = "python-dateutil" }, + { name = "tzlocal" }, + { name = "vine" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/b4/a1233943ab5c8ea05fb877a88a0a0622bf47444b99e4991a8045ac37ea1d/celery-5.6.3.tar.gz", hash = "sha256:177006bd2054b882e9f01be59abd8529e88879ef50d7918a7050c5a9f4e12912", size = 1742243, upload-time = "2026-03-26T12:14:51.76Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/c9/6eccdda96e098f7ae843162db2d3c149c6931a24fda69fe4ab84d0027eb5/celery-5.6.3-py3-none-any.whl", hash = "sha256:0808f42f80909c4d5833202360ffafb2a4f83f4d8e23e1285d926610e9a7afa6", size = 451235, upload-time = "2026-03-26T12:14:49.491Z" }, +] + [[package]] name = "certifi" version = "2025.6.15" @@ -655,6 +706,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, ] +[[package]] +name = "click-didyoumean" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/30/ce/217289b77c590ea1e7c24242d9ddd6e249e52c795ff10fac2c50062c48cb/click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463", size = 3089, upload-time = "2024-03-24T08:22:07.499Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/5b/974430b5ffdb7a4f1941d13d83c64a0395114503cc357c6b9ae4ce5047ed/click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c", size = 3631, upload-time = "2024-03-24T08:22:06.356Z" }, +] + +[[package]] +name = "click-plugins" +version = "1.1.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/a4/34847b59150da33690a36da3681d6bbc2ec14ee9a846bc30a6746e5984e4/click_plugins-1.1.1.2.tar.gz", hash = "sha256:d7af3984a99d243c131aa1a828331e7630f4a88a9741fd05c927b204bcf92261", size = 8343, upload-time = "2025-06-25T00:47:37.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/9a/2abecb28ae875e39c8cad711eb1186d8d14eab564705325e77e4e6ab9ae5/click_plugins-1.1.1.2-py2.py3-none-any.whl", hash = "sha256:008d65743833ffc1f5417bf0e78e8d2c23aab04d9745ba817bd3e71b0feb6aa6", size = 11051, upload-time = "2025-06-25T00:47:36.731Z" }, +] + +[[package]] +name = "click-repl" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "prompt-toolkit" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/50/bea78619ff1fc0fbd61882f64a1302a8abb2ea0b3db92907042d0e362df2/click_repl-0.4.1.tar.gz", hash = "sha256:c32a1cf6f95e5bd6e92076f81ce24eafd33f2f0ffb0135887e335b8e446d1c0b", size = 16403, upload-time = "2026-10-05T06:01:57.607Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/f6/12dc0f2e0159c2b416818b7fedcda15b520043773364a81d7389809a5af5/click_repl-0.4.1-py3-none-any.whl", hash = "sha256:5cb10881d4c5ebaa8695eceb69911af3062ee78342812b713564b17aad333eb5", size = 14988, upload-time = "2026-10-05T06:01:55.611Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -928,6 +1017,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] +[[package]] +name = "fastapi" +version = "0.141.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/02/91e3416a8fdd715abb903a952a6bec7cdd8d14eed55d415fc8595524c319/fastapi-0.141.1.tar.gz", hash = "sha256:e8822fc40db1e1858054d7a949a888695bc9bdce70139178e33bd2871a453ca1", size = 425799, upload-time = "2026-07-29T17:18:05.568Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/03/10388a42375ee7e4ac9b94eb2c5c569c8b5795e377e701c9ac3ad63de890/fastapi-0.141.1-py3-none-any.whl", hash = "sha256:bfb91aa2d334c61cb35ba9a116fc123b3d3df31640b801cf57a7a78ec3f603b3", size = 131954, upload-time = "2026-07-29T17:18:04.364Z" }, +] + [[package]] name = "fastmcp" version = "3.2.0" @@ -1672,6 +1777,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] +[[package]] +name = "kombu" +version = "5.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "amqp" }, + { name = "packaging" }, + { name = "tzdata" }, + { name = "vine" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/a5/607e533ed6c83ae1a696969b8e1c137dfebd5759a2e9682e26ff1b97740b/kombu-5.6.2.tar.gz", hash = "sha256:8060497058066c6f5aed7c26d7cd0d3b574990b09de842a8c5aaed0b92cc5a55", size = 472594, upload-time = "2025-12-29T20:30:07.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/0f/834427d8c03ff1d7e867d3db3d176470c64871753252b21b4f4897d1fa45/kombu-5.6.2-py3-none-any.whl", hash = "sha256:efcfc559da324d41d61ca311b0c64965ea35b4c55cc04ee36e55386145dace93", size = 214219, upload-time = "2025-12-29T20:30:05.74Z" }, +] + [[package]] name = "langchain" version = "1.4.4" @@ -2609,6 +2729,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/3a/8865d6754e61c9fb170cdd530a124a53769ee5f740236064816eb0ca7301/opentelemetry_exporter_otlp_proto_http-1.40.0-py3-none-any.whl", hash = "sha256:a8d1dab28f504c5d96577d6509f80a8150e44e8f45f82cdbe0e34c99ab040069", size = 19960, upload-time = "2026-03-04T14:17:07.153Z" }, ] +[[package]] +name = "opentelemetry-instrumentation" +version = "0.61b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "packaging" }, + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/37/6bf8e66bfcee5d3c6515b79cb2ee9ad05fe573c20f7ceb288d0e7eeec28c/opentelemetry_instrumentation-0.61b0.tar.gz", hash = "sha256:cb21b48db738c9de196eba6b805b4ff9de3b7f187e4bbf9a466fa170514f1fc7", size = 32606, upload-time = "2026-03-04T14:20:16.825Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/3e/f6f10f178b6316de67f0dfdbbb699a24fbe8917cf1743c1595fb9dcdd461/opentelemetry_instrumentation-0.61b0-py3-none-any.whl", hash = "sha256:92a93a280e69788e8f88391247cc530fd81f16f2b011979d4d6398f805cfbc63", size = 33448, upload-time = "2026-03-04T14:19:02.447Z" }, +] + +[[package]] +name = "opentelemetry-instrumentation-celery" +version = "0.61b0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/43/e79108a804d16b1dc8ff28edd0e94ac393cf6359a5adcd7cdd2ec4be85f4/opentelemetry_instrumentation_celery-0.61b0.tar.gz", hash = "sha256:0e352a567dc89ed8bc083fc635035ce3c5b96bbbd92831ffd676e93b87f8e94f", size = 14780, upload-time = "2026-03-04T14:20:27.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/ed/c05f3c84b455654eb6c047474ffde61ed92efc24030f64213c98bca9d44b/opentelemetry_instrumentation_celery-0.61b0-py3-none-any.whl", hash = "sha256:01235733ff0cdf571cb03b270645abb14b9c8d830313dc5842097ec90146320b", size = 13856, upload-time = "2026-03-04T14:19:20.98Z" }, +] + [[package]] name = "opentelemetry-proto" version = "1.40.0" @@ -2902,10 +3051,12 @@ otel = [ ] test = [ { name = "anthropic" }, + { name = "celery" }, { name = "claude-agent-sdk" }, { name = "coverage" }, { name = "django" }, { name = "djangorestframework" }, + { name = "fastapi" }, { name = "fastmcp" }, { name = "flask" }, { name = "freezegun" }, @@ -2922,6 +3073,7 @@ test = [ { name = "mcp" }, { name = "openai-agents" }, { name = "opentelemetry-exporter-otlp-proto-http" }, + { name = "opentelemetry-instrumentation-celery" }, { name = "opentelemetry-sdk" }, { name = "parameterized" }, { name = "pydantic" }, @@ -2946,12 +3098,14 @@ dev = [ [package.metadata] requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -2975,6 +3129,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, @@ -3023,6 +3178,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, ] +[[package]] +name = "prompt-toolkit" +version = "3.0.53" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/ea/39b988c938f75cb75d7045b5c69f8bfed47ee2152c8837fb403de29d6fb8/prompt_toolkit-3.0.53.tar.gz", hash = "sha256:9ec8a0ad96d5c56148b3f914aa79c1564c3fde5d2e6b876e7bc327e353cf8fa6", size = 435492, upload-time = "2026-07-26T20:56:14.758Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/6f/84908cad2d6aa5144abcf7b42709fe4fdb459bc640ec7ac5786e7693dabc/prompt_toolkit-3.0.53-py3-none-any.whl", hash = "sha256:01c0891d7f9237d5e339f7d3e42cdae80b7534abb1c7c0e3352efba6231492f2", size = 392288, upload-time = "2026-07-26T20:56:12.512Z" }, +] + [[package]] name = "propcache" version = "0.3.2" @@ -4195,6 +4362,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] +[[package]] +name = "tzlocal" +version = "5.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/81/5b/879b2f932adfa7a053c360d50bc896c977fa6426109185f7c12ebdd0cb9d/tzlocal-5.4.4.tar.gz", hash = "sha256:8dbb8660838688a7b6ba4fed31d18dedf842afb4d47ca050d6d891c2c15f3be4", size = 31170, upload-time = "2026-06-29T08:03:40.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/a4/017a7a6cbe387d961a688ec31364ae60a5c4e22c96ae9921b79a947c855d/tzlocal-5.4.4-py3-none-any.whl", hash = "sha256:aae09f0126a8a86fa736be266eb4a471380d26a0de3bc14844e7821fee3e2a15", size = 18115, upload-time = "2026-06-29T08:03:38.666Z" }, +] + [[package]] name = "uncalled-for" version = "0.3.2" @@ -4256,6 +4435,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl", hash = "sha256:96c30f5c7abe6f74ae8900a70e92b85ad6613b745d4879eb9b16ccad15645359", size = 68830, upload-time = "2026-03-16T06:19:48.325Z" }, ] +[[package]] +name = "vine" +version = "5.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/e4/d07b5f29d283596b9727dd5275ccbceb63c44a1a82aa9e4bfd20426762ac/vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0", size = 48980, upload-time = "2023-11-05T08:46:53.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/ff/7c0c86c43b3cbb927e0ccc0255cb4057ceba4799cd44ae95174ce8e8b5b2/vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc", size = 9636, upload-time = "2023-11-05T08:46:51.205Z" }, +] + [[package]] name = "virtualenv" version = "21.7.13" @@ -4389,6 +4577,42 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/f9/45d021e4a5cc7b9dd567f7cbb06d3b75f751a690063fb6cc7ec60f4e46b7/watchfiles-1.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0", size = 457771, upload-time = "2026-05-18T04:30:56.331Z" }, ] +[[package]] +name = "wcwidth" +version = "0.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/b4/7830542634bb2d3e62aa3b586a72d5b3b6c91c3168929e7000ef3fed041d/wcwidth-0.9.2.tar.gz", hash = "sha256:ae0ef90b90f6af38b54f1fe6d58662ec33b3cb4b8391958a62416d654231727b", size = 955039, upload-time = "2026-10-05T00:24:05.521Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/1e/4532a81fb9dfbf4114a816775e0a36c3a64ee1d1f4bba2094e2da50be5dc/wcwidth-0.9.2-cp310-abi3-macosx_10_9_x86_64.whl", hash = "sha256:7ef5a940bd5e30bac6e721f1a48fce0cd7bb3ece19e9c5d139e72c76c35cfd07", size = 605343, upload-time = "2026-10-05T00:23:22.649Z" }, + { url = "https://files.pythonhosted.org/packages/a0/07/cb6940e81134b7ed25fa312ee9ab536a63db0793b149f88a90e603ceace9/wcwidth-0.9.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:ae0800c5339423cc53d33a266ad264b42ba8aaa16d4464f6e6b1bee607f50b17", size = 609960, upload-time = "2026-10-05T00:23:27.049Z" }, + { url = "https://files.pythonhosted.org/packages/a4/80/15ad05d40bfa99155639fb9e13b3d77083aa0fab893c816db2543d29005c/wcwidth-0.9.2-cp310-abi3-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:9e542f1f8475b78452a295495d7a5bc3ead565112e9446a64dc93462a41c2a79", size = 762566, upload-time = "2026-10-05T00:23:38.322Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f0/b8ef7758003d66b60f093695831a86dcc726aac01ee6446ffcbda27b61e3/wcwidth-0.9.2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:674b518af28d38ee645ff97b74f5760abee5fad4bac74413bfc4b881ef2ce724", size = 771632, upload-time = "2026-10-05T00:23:32.448Z" }, + { url = "https://files.pythonhosted.org/packages/db/6c/f940133c71427c208575910e981942bd78c98b1f7cd0d1425ca4b7457c04/wcwidth-0.9.2-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:751bef0ab404b6a1dc028b56b4b85d46486be1c55833f80da533e42dc691f389", size = 769763, upload-time = "2026-10-05T00:23:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/285f862826f721964ec7c42f81dc53d23afbd723a0f4cd989651f8218e25/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c3d80f39ba4653a595edae9aa46a509d14883790a8fc23c5db221ceb207f64b7", size = 782134, upload-time = "2026-10-05T00:23:33.926Z" }, + { url = "https://files.pythonhosted.org/packages/c2/2d/64aa54882a5d556d3654c1f926d9118b797461033e23a158409941a37c8f/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:0a47e03d8293590ecce66c45dc20ff7b4b885e3c78093722239585eca0d77ab2", size = 782851, upload-time = "2026-10-05T00:23:41.974Z" }, + { url = "https://files.pythonhosted.org/packages/59/39/52389f6de7fe2e9c14ceb8253dd99034bd86e1c87847ea3c100a97dded9a/wcwidth-0.9.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:67d901a4ad99249eb775b4ee4769ca97fa405d35a75f46e83166910a47003f04", size = 784621, upload-time = "2026-10-05T00:23:43.449Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/20225500a076ace27bbcc8a6fd7c55125133c57a618816c7b7b8b73070b1/wcwidth-0.9.2-cp310-abi3-win32.whl", hash = "sha256:ee1fd0db9d9fd711a70f3e7765e0e04c05d26982fa05361456163062549d7da4", size = 593123, upload-time = "2026-10-05T00:23:55.953Z" }, + { url = "https://files.pythonhosted.org/packages/5a/d6/b0690f55ea0483530a18bac917fbadbf54f35122510446fc370f5f1c2453/wcwidth-0.9.2-cp310-abi3-win_amd64.whl", hash = "sha256:2a9746de704242bd4fdaabb31dd46b82f694a56a8d21081ad89b679a89da9fec", size = 597827, upload-time = "2026-10-05T00:23:57.489Z" }, + { url = "https://files.pythonhosted.org/packages/e5/11/6ecf4e9e268ab1a4ec617ffcccc2ee4a71301625f5490912dbaba462fa9c/wcwidth-0.9.2-cp310-abi3-win_arm64.whl", hash = "sha256:b9c6ab615e03723b7f8760ea2f27758d656e7e13b51515c9dca5c3e8b04612fa", size = 598415, upload-time = "2026-10-05T00:23:51.517Z" }, + { url = "https://files.pythonhosted.org/packages/4e/41/549eef1ab767032bdbdc1f0ab655d404b082b1e9a1dab1361dbba90f64ed/wcwidth-0.9.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eda88ffdc97c0fbf193d407114f2c7a54b379f67f6e52a7531ee3b9fe749eca7", size = 606555, upload-time = "2026-10-05T00:23:24.188Z" }, + { url = "https://files.pythonhosted.org/packages/9b/64/a875ed7ea71cacadc0ae11b5fd3fac3486efd58bb25e67a7344248dceadd/wcwidth-0.9.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1bf361c8705576760623b4724ae564666d73b016f9a778bcfd1c7345378ef4ec", size = 610829, upload-time = "2026-10-05T00:23:28.563Z" }, + { url = "https://files.pythonhosted.org/packages/c6/98/513095e484fe79b6f2613d6a72f855f5d56b65e15c215c2a6746fbc638f5/wcwidth-0.9.2-cp314-cp314t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:97b878d1e158da5ed9ac5aac53fa3a55e282103af6a09ec353865613d1a31a76", size = 775819, upload-time = "2026-10-05T00:23:45.116Z" }, + { url = "https://files.pythonhosted.org/packages/22/fc/c02f3eec57224731e78f84b68e272250f784b6205acc7e0dcef6a7c23a0e/wcwidth-0.9.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:59dab4049cbd982b478bca098528df2c79a9160636a3a163ffebffcbd7d1b892", size = 786915, upload-time = "2026-10-05T00:23:35.323Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6f/b0529a79bac3fe8d94f32b4237a13dbc3f955508753f6a6f06c73d679dc2/wcwidth-0.9.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb08ceb501d6aaf94066c3ee122dd825b152df40ff0bd0df4dc27126233b948e", size = 784186, upload-time = "2026-10-05T00:23:46.366Z" }, + { url = "https://files.pythonhosted.org/packages/d5/bd/6357c84ca9a734bfc735b7c48dbe21336b3777fab8a4101d14976dfe49a7/wcwidth-0.9.2-cp314-cp314t-win32.whl", hash = "sha256:8b4e381590b9b7390e07e22b2c0c1bb96ce50e1d2243c866d9387600362d51ed", size = 600791, upload-time = "2026-10-05T00:23:59.398Z" }, + { url = "https://files.pythonhosted.org/packages/98/de/037591ca18d897cc2179559dde72e6efc6ce0c90e9cd1e6bca4e87c38b4b/wcwidth-0.9.2-cp314-cp314t-win_amd64.whl", hash = "sha256:f2f7b3bba5a5d5f31fc350fd36ce5b84b693c83b7eb95ee630b720da5a5ce06f", size = 605463, upload-time = "2026-10-05T00:24:01.049Z" }, + { url = "https://files.pythonhosted.org/packages/d0/07/c9d96e106d938d26f7ab639bc80b8199359a1645ba6e3498413313ab6f38/wcwidth-0.9.2-cp314-cp314t-win_arm64.whl", hash = "sha256:734aa9405b321d1042301aa19c943c4731ee9e3460e4f8feea3299c064c97a14", size = 605936, upload-time = "2026-10-05T00:23:52.765Z" }, + { url = "https://files.pythonhosted.org/packages/82/8a/a28d61d910005ac93dfe48be3a0ebaa49352d88cebd25323e69e6ff2f4a8/wcwidth-0.9.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:42dbcb76ce8af39e2c9db410ac3f9bdf4e47eb41d6f44525952f172d3d98f724", size = 606575, upload-time = "2026-10-05T00:23:25.663Z" }, + { url = "https://files.pythonhosted.org/packages/01/c2/a3c66bd32766c8f4d6dc47d572532ba014fe5be30489f2576aff7cada363/wcwidth-0.9.2-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:138e1f8898e431b2f2d7881f8ca8d75591c1d3c21aa53f54e989bd6b39811da2", size = 611045, upload-time = "2026-10-05T00:23:30.421Z" }, + { url = "https://files.pythonhosted.org/packages/ec/8a/d39964f8f8c019d7d439b9b501d3e7bb42fee69f00354040ba0b27b5824c/wcwidth-0.9.2-cp315-cp315t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5175609bf8cc7398a5f48aa35207bd64ebf9f45e4c70df65f7fdc7a988041a3c", size = 778143, upload-time = "2026-10-05T00:23:47.7Z" }, + { url = "https://files.pythonhosted.org/packages/2f/53/525da13e8f9ff7b5b4e74ec6f8d68bdee63905796972e086c6b1b96670d2/wcwidth-0.9.2-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5f669ae8c3d969c72032f9cdee019674b666e522d45e1e2099a2e9dda4a341d", size = 786630, upload-time = "2026-10-05T00:23:36.967Z" }, + { url = "https://files.pythonhosted.org/packages/ef/9f/d6a0c6df354b9d93466548a65cbf4ffcb48c719bbd307504cf3e76740837/wcwidth-0.9.2-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:196b47cf32f9df27ccda6dc513237f3c2429c4c659db428d60a5bc443d10f270", size = 784839, upload-time = "2026-10-05T00:23:49.88Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d7/3021feed1ed7926021ec134943ad3b24a2f7ea742cc9976461171482ed77/wcwidth-0.9.2-cp315-cp315t-win32.whl", hash = "sha256:0cd4f7f2e53905dcb110d213a4c8529b6733fa3d232d8c717f946cc69a10349b", size = 600845, upload-time = "2026-10-05T00:24:02.497Z" }, + { url = "https://files.pythonhosted.org/packages/63/80/6a03356d8ee38261e3a78cf89ee03d8e7f12c572d969237be00869e2dc73/wcwidth-0.9.2-cp315-cp315t-win_amd64.whl", hash = "sha256:33df042f96c61ed3cd5fb3742fba427553a635bc578799857a48aa79f774a0b9", size = 605441, upload-time = "2026-10-05T00:24:04.052Z" }, + { url = "https://files.pythonhosted.org/packages/0c/48/1a308a86a833fd12ff7a08d0d2491ff4a72c8a92d12f5ead8317630f771e/wcwidth-0.9.2-cp315-cp315t-win_arm64.whl", hash = "sha256:48719a9bc76c2f84238693fe5013571fa5beffa3621cf228f1f3a9e30dae84b8", size = 605885, upload-time = "2026-10-05T00:23:54.274Z" }, + { url = "https://files.pythonhosted.org/packages/9c/b4/0bfa065af506540d9d558e3e5548cff00bc1f9b24e6e2a8512498e8628de/wcwidth-0.9.2-py3-none-any.whl", hash = "sha256:89ca642c5bf0101157a09366be69fad0379db1f700ae39a920e103234573670e", size = 301667, upload-time = "2026-10-05T00:23:21.097Z" }, +] + [[package]] name = "websockets" version = "15.0.1" @@ -4469,6 +4693,75 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/2c/87f3254fd8ffd29e4c02732eee68a83a1d3c346ae39bc6822dcbcb697f2b/wheel-0.45.1-py3-none-any.whl", hash = "sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248", size = 72494, upload-time = "2024-11-23T00:18:21.207Z" }, ] +[[package]] +name = "wrapt" +version = "1.17.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/23/bb82321b86411eb51e5a5db3fb8f8032fd30bd7c2d74bfe936136b2fa1d6/wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04", size = 53482, upload-time = "2025-08-12T05:51:44.467Z" }, + { url = "https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2", size = 38676, upload-time = "2025-08-12T05:51:32.636Z" }, + { url = "https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c", size = 38957, upload-time = "2025-08-12T05:51:54.655Z" }, + { url = "https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775", size = 81975, upload-time = "2025-08-12T05:52:30.109Z" }, + { url = "https://files.pythonhosted.org/packages/f2/15/dd576273491f9f43dd09fce517f6c2ce6eb4fe21681726068db0d0467096/wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd", size = 83149, upload-time = "2025-08-12T05:52:09.316Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c4/5eb4ce0d4814521fee7aa806264bf7a114e748ad05110441cd5b8a5c744b/wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05", size = 82209, upload-time = "2025-08-12T05:52:10.331Z" }, + { url = "https://files.pythonhosted.org/packages/31/4b/819e9e0eb5c8dc86f60dfc42aa4e2c0d6c3db8732bce93cc752e604bb5f5/wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418", size = 81551, upload-time = "2025-08-12T05:52:31.137Z" }, + { url = "https://files.pythonhosted.org/packages/f8/83/ed6baf89ba3a56694700139698cf703aac9f0f9eb03dab92f57551bd5385/wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390", size = 36464, upload-time = "2025-08-12T05:53:01.204Z" }, + { url = "https://files.pythonhosted.org/packages/2f/90/ee61d36862340ad7e9d15a02529df6b948676b9a5829fd5e16640156627d/wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6", size = 38748, upload-time = "2025-08-12T05:53:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c3/cefe0bd330d389c9983ced15d326f45373f4073c9f4a8c2f99b50bfea329/wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18", size = 36810, upload-time = "2025-08-12T05:52:51.906Z" }, + { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, + { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" }, + { url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" }, + { url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" }, + { url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" }, + { url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" }, + { url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, + { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, + { url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" }, + { url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" }, + { url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" }, + { url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" }, + { url = "https://files.pythonhosted.org/packages/02/a2/cd864b2a14f20d14f4c496fab97802001560f9f41554eef6df201cd7f76c/wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39", size = 54132, upload-time = "2025-08-12T05:51:49.864Z" }, + { url = "https://files.pythonhosted.org/packages/d5/46/d011725b0c89e853dc44cceb738a307cde5d240d023d6d40a82d1b4e1182/wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235", size = 39091, upload-time = "2025-08-12T05:51:38.935Z" }, + { url = "https://files.pythonhosted.org/packages/2e/9e/3ad852d77c35aae7ddebdbc3b6d35ec8013af7d7dddad0ad911f3d891dae/wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c", size = 39172, upload-time = "2025-08-12T05:51:59.365Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f7/c983d2762bcce2326c317c26a6a1e7016f7eb039c27cdf5c4e30f4160f31/wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b", size = 87163, upload-time = "2025-08-12T05:52:40.965Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0f/f673f75d489c7f22d17fe0193e84b41540d962f75fce579cf6873167c29b/wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa", size = 87963, upload-time = "2025-08-12T05:52:20.326Z" }, + { url = "https://files.pythonhosted.org/packages/df/61/515ad6caca68995da2fac7a6af97faab8f78ebe3bf4f761e1b77efbc47b5/wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7", size = 86945, upload-time = "2025-08-12T05:52:21.581Z" }, + { url = "https://files.pythonhosted.org/packages/d3/bd/4e70162ce398462a467bc09e768bee112f1412e563620adc353de9055d33/wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4", size = 86857, upload-time = "2025-08-12T05:52:43.043Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b8/da8560695e9284810b8d3df8a19396a6e40e7518059584a1a394a2b35e0a/wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10", size = 37178, upload-time = "2025-08-12T05:53:12.605Z" }, + { url = "https://files.pythonhosted.org/packages/db/c8/b71eeb192c440d67a5a0449aaee2310a1a1e8eca41676046f99ed2487e9f/wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6", size = 39310, upload-time = "2025-08-12T05:53:11.106Z" }, + { url = "https://files.pythonhosted.org/packages/45/20/2cda20fd4865fa40f86f6c46ed37a2a8356a7a2fde0773269311f2af56c7/wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58", size = 37266, upload-time = "2025-08-12T05:52:56.531Z" }, + { url = "https://files.pythonhosted.org/packages/77/ed/dd5cf21aec36c80443c6f900449260b80e2a65cf963668eaef3b9accce36/wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a", size = 56544, upload-time = "2025-08-12T05:51:51.109Z" }, + { url = "https://files.pythonhosted.org/packages/8d/96/450c651cc753877ad100c7949ab4d2e2ecc4d97157e00fa8f45df682456a/wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067", size = 40283, upload-time = "2025-08-12T05:51:39.912Z" }, + { url = "https://files.pythonhosted.org/packages/d1/86/2fcad95994d9b572db57632acb6f900695a648c3e063f2cd344b3f5c5a37/wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454", size = 40366, upload-time = "2025-08-12T05:52:00.693Z" }, + { url = "https://files.pythonhosted.org/packages/64/0e/f4472f2fdde2d4617975144311f8800ef73677a159be7fe61fa50997d6c0/wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e", size = 108571, upload-time = "2025-08-12T05:52:44.521Z" }, + { url = "https://files.pythonhosted.org/packages/cc/01/9b85a99996b0a97c8a17484684f206cbb6ba73c1ce6890ac668bcf3838fb/wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f", size = 113094, upload-time = "2025-08-12T05:52:22.618Z" }, + { url = "https://files.pythonhosted.org/packages/25/02/78926c1efddcc7b3aa0bc3d6b33a822f7d898059f7cd9ace8c8318e559ef/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056", size = 110659, upload-time = "2025-08-12T05:52:24.057Z" }, + { url = "https://files.pythonhosted.org/packages/dc/ee/c414501ad518ac3e6fe184753632fe5e5ecacdcf0effc23f31c1e4f7bfcf/wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804", size = 106946, upload-time = "2025-08-12T05:52:45.976Z" }, + { url = "https://files.pythonhosted.org/packages/be/44/a1bd64b723d13bb151d6cc91b986146a1952385e0392a78567e12149c7b4/wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977", size = 38717, upload-time = "2025-08-12T05:53:15.214Z" }, + { url = "https://files.pythonhosted.org/packages/79/d9/7cfd5a312760ac4dd8bf0184a6ee9e43c33e47f3dadc303032ce012b8fa3/wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116", size = 41334, upload-time = "2025-08-12T05:53:14.178Z" }, + { url = "https://files.pythonhosted.org/packages/46/78/10ad9781128ed2f99dbc474f43283b13fea8ba58723e98844367531c18e9/wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6", size = 38471, upload-time = "2025-08-12T05:52:57.784Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, +] + [[package]] name = "xxhash" version = "3.5.0" From bdcdbcd8728454f3783dc5d653df9cca2b21cdb0 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 15:21:36 +0000 Subject: [PATCH 46/70] chore: Release v7.75.0 [skip ci] (cherry picked from commit 908c77bc34e73aab009d04248131ccdbfe5ade5a) --- .sampo/changesets/asgi-otel-span-context.md | 5 ----- .sampo/changesets/celery-otel-span-context.md | 5 ----- .sampo/changesets/django-otel-span-context.md | 5 ----- .sampo/changesets/flask-otel-span-context.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 12 ++++++++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 10 files changed, 23 insertions(+), 25 deletions(-) delete mode 100644 .sampo/changesets/asgi-otel-span-context.md delete mode 100644 .sampo/changesets/celery-otel-span-context.md delete mode 100644 .sampo/changesets/django-otel-span-context.md delete mode 100644 .sampo/changesets/flask-otel-span-context.md diff --git a/.sampo/changesets/asgi-otel-span-context.md b/.sampo/changesets/asgi-otel-span-context.md deleted file mode 100644 index a3d821ea2..000000000 --- a/.sampo/changesets/asgi-otel-span-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Add active PostHog request IDs to existing OpenTelemetry spans in ASGI middleware. diff --git a/.sampo/changesets/celery-otel-span-context.md b/.sampo/changesets/celery-otel-span-context.md deleted file mode 100644 index 0cb6c9285..000000000 --- a/.sampo/changesets/celery-otel-span-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Add propagated task context to active Celery OpenTelemetry spans. diff --git a/.sampo/changesets/django-otel-span-context.md b/.sampo/changesets/django-otel-span-context.md deleted file mode 100644 index 90a517cd3..000000000 --- a/.sampo/changesets/django-otel-span-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: minor ---- - -Add an optional OpenTelemetry span processor for PostHog request IDs and enrich active Django request spans after request context is available. diff --git a/.sampo/changesets/flask-otel-span-context.md b/.sampo/changesets/flask-otel-span-context.md deleted file mode 100644 index fc475163a..000000000 --- a/.sampo/changesets/flask-otel-span-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Add available PostHog request IDs to active Flask OpenTelemetry request spans. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index eb45ccb44..f33e39997 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.114 — 2026-10-21 + +### Patch changes + +- Updated dependencies: posthog@7.75.0 + ## 0.1.113 — 2026-10-21 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 5a00661cf..8c2dc935b 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.113" +version = "0.1.114" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 9b6467603..5421d4df4 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,17 @@ # posthog +## 7.75.0 — 2026-10-21 + +### Minor changes + +- [5f01fe9](https://github.com/posthog/posthog-python/commit/5f01fe93b893944f9b04c9e0f0536df46810143f) Add an optional OpenTelemetry span processor for PostHog request IDs and enrich active Django request spans after request context is available. — Thanks @pauldambra! + +### Patch changes + +- [5ddb446](https://github.com/posthog/posthog-python/commit/5ddb4464a634a1dddf9b585cb9cf804c671a2edf) Add available PostHog request IDs to active Flask OpenTelemetry request spans. — Thanks @pauldambra! +- [5ddb446](https://github.com/posthog/posthog-python/commit/5ddb4464a634a1dddf9b585cb9cf804c671a2edf) Add propagated task context to active Celery OpenTelemetry spans. — Thanks @pauldambra! +- [5ddb446](https://github.com/posthog/posthog-python/commit/5ddb4464a634a1dddf9b585cb9cf804c671a2edf) Add active PostHog request IDs to existing OpenTelemetry spans in ASGI middleware. — Thanks @pauldambra! + ## 7.74.0 — 2026-10-21 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index bf1e6fa9c..1cd74dd98 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.74.0" +VERSION = "7.75.0" diff --git a/pyproject.toml b/pyproject.toml index c29f296c9..6c0481800 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.74.0" +version = "7.75.0" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 4fbfdc774..ef0b0e07c 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.113" +version = "0.1.114" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.74.0" +version = "7.75.0" source = { editable = "." } dependencies = [ { name = "distro" }, From 9cfc83110a86185190f7ad1b5a5db47efeea9a6b Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 15:21:43 +0000 Subject: [PATCH 47/70] Update generated references (cherry picked from commit a5b93eed7125a1ef7a9c9a442ec75487027f1f59) --- .../posthog-python-references-7.75.0.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.0.json diff --git a/references/posthog-python-references-7.75.0.json b/references/posthog-python-references-7.75.0.json new file mode 100644 index 000000000..23d13e277 --- /dev/null +++ b/references/posthog-python-references-7.75.0.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.0", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 2053aac41..23d13e277 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.74.0", + "version": "7.75.0", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 81f716440db51a470c8e1c00cdd631ce31f188e8 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Date: Thu, 22 Oct 2026 15:49:48 +0700 Subject: [PATCH 48/70] fix(flags): match explicit null properties with string operators (#1092) (cherry picked from commit e9056e3051911b72aa1c8f9d39eb08fa4b0b65c4) --- .../pompous-guardian-joukahainen.md | 5 +++ posthog/feature_flags.py | 18 ++++------ posthog/test/test_feature_flags.py | 35 +++++++++++++++++++ 3 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 .sampo/changesets/pompous-guardian-joukahainen.md diff --git a/.sampo/changesets/pompous-guardian-joukahainen.md b/.sampo/changesets/pompous-guardian-joukahainen.md new file mode 100644 index 000000000..e90ec2462 --- /dev/null +++ b/.sampo/changesets/pompous-guardian-joukahainen.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Fix local feature flag string and regex operators to match an explicit null property as "null", like the flags service. This can change flag values or selected variants for explicitly null person or group properties. Missing properties still allow remote evaluation fallback. diff --git a/posthog/feature_flags.py b/posthog/feature_flags.py index 7545306ea..049e2fe4e 100644 --- a/posthog/feature_flags.py +++ b/posthog/feature_flags.py @@ -698,6 +698,7 @@ def match_property( if ( operator not in NONE_VALUES_ALLOWED_OPERATORS + and operator not in STRING_OPERATORS and operator != "exact" and override_value is None ): @@ -750,17 +751,12 @@ def compute_exact_match(value, override_value): return not matched return matched - if operator == "regex": - return ( - is_valid_regex(str(value)) - and re.compile(str(value)).search(str(override_value)) is not None - ) - - if operator == "not_regex": - return ( - is_valid_regex(str(value)) - and re.compile(str(value)).search(str(override_value)) is None - ) + if operator in ("regex", "not_regex"): + if not is_valid_regex(str(value)): + return False + property_string = "null" if override_value is None else str(override_value) + matched = re.compile(str(value)).search(property_string) is not None + return not matched if operator == "not_regex" else matched if operator in ["is_date_before", "is_date_after"]: try: diff --git a/posthog/test/test_feature_flags.py b/posthog/test/test_feature_flags.py index 374cb3259..2c430336d 100644 --- a/posthog/test/test_feature_flags.py +++ b/posthog/test/test_feature_flags.py @@ -5654,6 +5654,41 @@ def test_string_operators_preserve_float_stringification( prop = self.property("key", value, operator) self.assertTrue(match_property(prop, {"key": property_value})) + @parameterized.expand( + [ + ("icontains", "nul", True), + ("icontains", "x", False), + ("not_icontains", "x", True), + ("not_icontains", "nul", False), + ("starts_with", "NU", True), + ("starts_with", "x", False), + ("not_starts_with", "x", True), + ("not_starts_with", "nu", False), + ("ends_with", "LL", True), + ("ends_with", "x", False), + ("not_ends_with", "x", True), + ("not_ends_with", "ll", False), + ("regex", "^nu", True), + ("regex", "Nu", False), + ("regex", "^None$", False), + ("regex", "x", False), + ("not_regex", "x", True), + ("not_regex", "^nu", False), + ("not_regex", "^None$", True), + ("regex", "[", False), + ("not_regex", "[", False), + ] + ) + def test_string_operators_match_explicit_null(self, operator, value, expected): + prop = self.property("key", value, operator) + self.assertEqual(expected, match_property(prop, {"key": None})) + + def test_string_operators_with_omitted_key_are_inconclusive(self): + for operator in posthog.feature_flags.STRING_OPERATORS: + with self.subTest(operator=operator): + with self.assertRaises(InconclusiveMatchError): + match_property(self.property("key", "x", operator), {}) + def test_match_properties_regex(self): property_a = self.property(key="key", value=r"\.com$", operator="regex") self.assertTrue(match_property(property_a, {"key": "value.com"})) From 89c339d83936f52502d5b7288752d21cba2f25c0 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 08:51:30 +0000 Subject: [PATCH 49/70] chore: Release v7.75.1 [skip ci] (cherry picked from commit 361ca83dbf06c3f1674b4b2c5be05ffcc555191e) --- .sampo/changesets/pompous-guardian-joukahainen.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/pompous-guardian-joukahainen.md diff --git a/.sampo/changesets/pompous-guardian-joukahainen.md b/.sampo/changesets/pompous-guardian-joukahainen.md deleted file mode 100644 index e90ec2462..000000000 --- a/.sampo/changesets/pompous-guardian-joukahainen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Fix local feature flag string and regex operators to match an explicit null property as "null", like the flags service. This can change flag values or selected variants for explicitly null person or group properties. Missing properties still allow remote evaluation fallback. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index f33e39997..d388120dd 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.115 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.1 + ## 0.1.114 — 2026-10-21 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 8c2dc935b..539c7e40c 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.114" +version = "0.1.115" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 5421d4df4..e0ac0dbc8 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.75.1 — 2026-10-22 + +### Patch changes + +- [e9056e3](https://github.com/posthog/posthog-python/commit/e9056e3051911b72aa1c8f9d39eb08fa4b0b65c4) Fix local feature flag string and regex operators to match an explicit null property as "null", like the flags service. This can change flag values or selected variants for explicitly null person or group properties. Missing properties still allow remote evaluation fallback. — Thanks @marandaneto! + ## 7.75.0 — 2026-10-21 ### Minor changes diff --git a/posthog/version.py b/posthog/version.py index 1cd74dd98..bf1cd1b6f 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.0" +VERSION = "7.75.1" diff --git a/pyproject.toml b/pyproject.toml index 6c0481800..958cb60c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.0" +version = "7.75.1" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index ef0b0e07c..dc942f2d6 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.114" +version = "0.1.115" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.0" +version = "7.75.1" source = { editable = "." } dependencies = [ { name = "distro" }, From f41e0458332b93c22bbb8c55ba680a428e2b1a01 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 08:51:36 +0000 Subject: [PATCH 50/70] Update generated references (cherry picked from commit 5e296d88138157ee730916a293044e0c25fc7aef) --- .../posthog-python-references-7.75.1.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.1.json diff --git a/references/posthog-python-references-7.75.1.json b/references/posthog-python-references-7.75.1.json new file mode 100644 index 000000000..738621f18 --- /dev/null +++ b/references/posthog-python-references-7.75.1.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.1", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 23d13e277..738621f18 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.0", + "version": "7.75.1", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From bee52fba51886d27a08313dc8aa700aa54710956 Mon Sep 17 00:00:00 2001 From: mosafariuk Date: Thu, 22 Oct 2026 11:08:25 +0100 Subject: [PATCH 51/70] fix(ai): capture OpenAI chat custom tool calls instead of raising (#1098) A custom tool call has `custom` instead of `function`, so formatting the response raised AttributeError from the wrapped create(), after the provider call had succeeded. Read the name and input from `custom`, matching PostHog/posthog-js#5251. (cherry picked from commit 4697e6fcc837d1de3508a8b53273f609b6d63415) --- .sampo/changesets/openai-custom-tool-calls.md | 5 ++ posthog/ai/openai/openai_converter.py | 14 ++- posthog/test/ai/openai/test_openai.py | 86 +++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 .sampo/changesets/openai-custom-tool-calls.md diff --git a/.sampo/changesets/openai-custom-tool-calls.md b/.sampo/changesets/openai-custom-tool-calls.md new file mode 100644 index 000000000..49f5b66b6 --- /dev/null +++ b/.sampo/changesets/openai-custom-tool-calls.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Capture Chat Completions responses that contain custom tool calls instead of raising `AttributeError` from the wrapped `create()` call. diff --git a/posthog/ai/openai/openai_converter.py b/posthog/ai/openai/openai_converter.py index 0f391fb9f..21c58478b 100644 --- a/posthog/ai/openai/openai_converter.py +++ b/posthog/ai/openai/openai_converter.py @@ -153,13 +153,23 @@ def format_openai_response(response: Any) -> List[FormattedMessage]: if hasattr(choice.message, "tool_calls") and choice.message.tool_calls: for tool_call in choice.message.tool_calls: + # Custom tools carry their free-form text in `custom.input`, + # with no `function` object. + is_custom = getattr(tool_call, "type", None) == "custom" + call = getattr( + tool_call, "custom" if is_custom else "function", None + ) + if call is None: + continue content.append( { "type": "function", "id": tool_call.id, "function": { - "name": tool_call.function.name, - "arguments": tool_call.function.arguments, + "name": call.name, + "arguments": call.input + if is_custom + else call.arguments, }, } ) diff --git a/posthog/test/ai/openai/test_openai.py b/posthog/test/ai/openai/test_openai.py index 95fdc22b0..875c08c43 100644 --- a/posthog/test/ai/openai/test_openai.py +++ b/posthog/test/ai/openai/test_openai.py @@ -736,6 +736,92 @@ def test_tool_calls_only_no_content(mock_client, mock_openai_response_tool_calls assert props["$ai_http_status"] == 200 +@pytest.mark.parametrize("is_async", [False, True]) +async def test_custom_tool_calls_are_captured(mock_client, is_async): + """A custom tool call has `custom` instead of `function`. The wrapped call + must return the completion and capture it, not raise AttributeError.""" + completion = ChatCompletion.model_validate( + { + "id": "test", + "model": "gpt-5", + "object": "chat.completion", + "created": 0, + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "role": "assistant", + "content": None, + "tool_calls": [ + { + "id": "call_fn", + "type": "function", + "function": { + "name": "get_weather", + "arguments": '{"location": "New York"}', + }, + }, + { + "id": "call_custom", + "type": "custom", + "custom": {"name": "code_exec", "input": "print(1)"}, + }, + ], + }, + } + ], + "usage": {"prompt_tokens": 25, "completion_tokens": 10, "total_tokens": 35}, + } + ) + kwargs = dict( + model="gpt-5", + messages=[{"role": "user", "content": "Run it"}], + tools=[{"type": "custom", "custom": {"name": "code_exec"}}], + posthog_distinct_id="test-id", + ) + + if is_async: + with patch( + "openai.resources.chat.completions.AsyncCompletions.create", + new_callable=AsyncMock, + return_value=completion, + ): + client = AsyncOpenAI(api_key="test-key", posthog_client=mock_client) + response = await client.chat.completions.create(**kwargs) + else: + with patch( + "openai.resources.chat.completions.Completions.create", + return_value=completion, + ): + client = OpenAI(api_key="test-key", posthog_client=mock_client) + response = client.chat.completions.create(**kwargs) + + assert response == completion + assert mock_client.capture_ai.call_count == 1 + props = mock_client.capture_ai.call_args[1]["properties"] + assert props["$ai_output_choices"] == [ + { + "role": "assistant", + "content": [ + { + "type": "function", + "id": "call_fn", + "function": { + "name": "get_weather", + "arguments": '{"location": "New York"}', + }, + }, + { + "type": "function", + "id": "call_custom", + "function": {"name": "code_exec", "arguments": "print(1)"}, + }, + ], + } + ] + + def test_responses_api_tool_calls(mock_client, mock_responses_api_with_tool_calls): with patch( "openai.resources.responses.Responses.create", From 7e02dda59f0f5afe13afc94a6396a9cc489a0700 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:10:48 +0000 Subject: [PATCH 52/70] chore: Release v7.75.2 [skip ci] (cherry picked from commit e63a898f2689be0b7a1f77c643ae5e62c5d25d15) --- .sampo/changesets/openai-custom-tool-calls.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/openai-custom-tool-calls.md diff --git a/.sampo/changesets/openai-custom-tool-calls.md b/.sampo/changesets/openai-custom-tool-calls.md deleted file mode 100644 index 49f5b66b6..000000000 --- a/.sampo/changesets/openai-custom-tool-calls.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Capture Chat Completions responses that contain custom tool calls instead of raising `AttributeError` from the wrapped `create()` call. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index d388120dd..9e72ba64b 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.116 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.2 + ## 0.1.115 — 2026-10-22 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 539c7e40c..5fa1a76ca 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.115" +version = "0.1.116" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index e0ac0dbc8..8f249b1a0 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.75.2 — 2026-10-22 + +### Patch changes + +- [4697e6f](https://github.com/posthog/posthog-python/commit/4697e6fcc837d1de3508a8b53273f609b6d63415) Capture Chat Completions responses that contain custom tool calls instead of raising `AttributeError` from the wrapped `create()` call. — Thanks @mosafariuk! + ## 7.75.1 — 2026-10-22 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index bf1cd1b6f..1f9f0be5a 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.1" +VERSION = "7.75.2" diff --git a/pyproject.toml b/pyproject.toml index 958cb60c8..463ca4618 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.1" +version = "7.75.2" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index dc942f2d6..bab629ad0 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.115" +version = "0.1.116" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.1" +version = "7.75.2" source = { editable = "." } dependencies = [ { name = "distro" }, From 5ac32f413ebbd0a1244b5b8df0b676c6ba27eb33 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:10:54 +0000 Subject: [PATCH 53/70] Update generated references (cherry picked from commit e9710ec2817e5104e9f9a713acdd8734e9caf485) --- .../posthog-python-references-7.75.2.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.2.json diff --git a/references/posthog-python-references-7.75.2.json b/references/posthog-python-references-7.75.2.json new file mode 100644 index 000000000..6b0cdcdf1 --- /dev/null +++ b/references/posthog-python-references-7.75.2.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.2", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 738621f18..6b0cdcdf1 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.1", + "version": "7.75.2", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From fa46ea1ec210aac7e9aa964fb7c7612bb83e7551 Mon Sep 17 00:00:00 2001 From: alexcastgonz <82875882+pcbeingused333@users.noreply.github.com> Date: Thu, 22 Oct 2026 06:17:05 -0400 Subject: [PATCH 54/70] fix(ai): record mid-stream errors on streamed OpenAI, Anthropic and Gemini events (#1094) * fix(ai): record mid-stream errors on streamed OpenAI, Anthropic and Gemini events capture_streaming_event hard-coded $ai_http_status=200, and the stream generators only had a finally block. When the provider stream raised after the first chunk (overloaded, connection reset), the event was sent as a success with no $ai_is_error/$ai_error, unlike the non-streaming path. Catch the exception in each sync and async generator, pass it through StreamingEventData, and re-raise unchanged. The event now carries $ai_is_error, $ai_error and the error's status code (0 when it has none). Co-Authored-By: Claude Sonnet 5.5 * fix(ai): pass the stream error to StreamingEventData directly and update the API snapshot mypy 1.16 rejected splatting {"error": error} into StreamingEventData(...) (typeddict-item). The field accepts None and capture_streaming_event reads it with .get(), so pass error=error. Regenerate the public API snapshot for the new StreamingEventData.error field. Co-Authored-By: Claude Sonnet 5.5 --------- Co-authored-by: Claude Sonnet 5.5 (cherry picked from commit dc2a2b4e33659e7909786fa48c625d37dc4da94d) --- .../changesets/streaming-midstream-error.md | 5 + posthog/ai/anthropic/anthropic.py | 7 + posthog/ai/anthropic/anthropic_async.py | 7 + posthog/ai/gemini/_shared.py | 2 + posthog/ai/gemini/gemini.py | 5 + posthog/ai/gemini/gemini_async.py | 5 + posthog/ai/openai/_streaming.py | 2 + posthog/ai/openai/openai.py | 14 + posthog/ai/openai/openai_async.py | 14 + posthog/ai/types.py | 1 + posthog/ai/utils.py | 8 +- .../test/ai/test_stream_midstream_error.py | 269 ++++++++++++++++++ references/public_api_snapshot.txt | 1 + 13 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 .sampo/changesets/streaming-midstream-error.md create mode 100644 posthog/test/ai/test_stream_midstream_error.py diff --git a/.sampo/changesets/streaming-midstream-error.md b/.sampo/changesets/streaming-midstream-error.md new file mode 100644 index 000000000..b66920190 --- /dev/null +++ b/.sampo/changesets/streaming-midstream-error.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Streamed OpenAI, Anthropic and Gemini generations that raise mid-stream are now captured with `$ai_is_error` and `$ai_error` (and the error's status code as `$ai_http_status`) instead of being recorded as a successful 200. The error is still re-raised to the caller, matching what non-streaming calls already did. diff --git a/posthog/ai/anthropic/anthropic.py b/posthog/ai/anthropic/anthropic.py index df8230193..e0b80ffe3 100644 --- a/posthog/ai/anthropic/anthropic.py +++ b/posthog/ai/anthropic/anthropic.py @@ -188,10 +188,14 @@ def _track_streaming_response( accumulator = _AnthropicStreamAccumulator() def generator(): + stream_error: Optional[BaseException] = None try: for event in response: accumulator.consume(event) yield event + except Exception as exc: + stream_error = exc + raise finally: end_time = time.time() latency = end_time - start_time @@ -208,6 +212,7 @@ def generator(): accumulator.content_blocks, accumulator.accumulated_content, stop_reason=accumulator.stop_reason, + error=stream_error, ) return _StreamWrapper(generator(), stream=response) @@ -225,6 +230,7 @@ def _capture_streaming_event( content_blocks: List[StreamingContentBlock], accumulated_content: str, stop_reason: Optional[str] = None, + error: Optional[BaseException] = None, ): from posthog.ai.types import StreamingEventData from posthog.ai.anthropic.anthropic_converter import ( @@ -252,6 +258,7 @@ def _capture_streaming_event( privacy_mode=posthog_privacy_mode, groups=posthog_groups, stop_reason=stop_reason, + error=error, ) # Use the common capture function diff --git a/posthog/ai/anthropic/anthropic_async.py b/posthog/ai/anthropic/anthropic_async.py index 42b7799da..ac9be3741 100644 --- a/posthog/ai/anthropic/anthropic_async.py +++ b/posthog/ai/anthropic/anthropic_async.py @@ -188,10 +188,14 @@ def _track_streaming_response( accumulator = _AnthropicStreamAccumulator() async def generator(): + stream_error: Optional[BaseException] = None try: async for event in response: accumulator.consume(event) yield event + except Exception as exc: + stream_error = exc + raise finally: end_time = time.time() latency = end_time - start_time @@ -208,6 +212,7 @@ async def generator(): accumulator.content_blocks, accumulator.accumulated_content, stop_reason=accumulator.stop_reason, + error=stream_error, ) return AsyncStreamWrapper(generator(), stream=response) @@ -225,6 +230,7 @@ async def _capture_streaming_event( content_blocks: List[StreamingContentBlock], accumulated_content: str, stop_reason: Optional[str] = None, + error: Optional[BaseException] = None, ): from posthog.ai.types import StreamingEventData from posthog.ai.anthropic.anthropic_converter import ( @@ -252,6 +258,7 @@ async def _capture_streaming_event( privacy_mode=posthog_privacy_mode, groups=posthog_groups, stop_reason=stop_reason, + error=error, ) # Use the common capture function diff --git a/posthog/ai/gemini/_shared.py b/posthog/ai/gemini/_shared.py index 356abb6fc..31900b40c 100644 --- a/posthog/ai/gemini/_shared.py +++ b/posthog/ai/gemini/_shared.py @@ -194,6 +194,7 @@ def _capture_streaming_event( latency: float, output: Any, stop_reason: Optional[str] = None, + error: Optional[BaseException] = None, ) -> None: formatted_input = merge_system_prompt( {"contents": contents, **kwargs}, "gemini" @@ -213,6 +214,7 @@ def _capture_streaming_event( privacy_mode=privacy_mode, groups=groups, stop_reason=stop_reason, + error=error, ) capture_streaming_event(self._ph_client, event_data) diff --git a/posthog/ai/gemini/gemini.py b/posthog/ai/gemini/gemini.py index 573d56512..71224af9f 100644 --- a/posthog/ai/gemini/gemini.py +++ b/posthog/ai/gemini/gemini.py @@ -266,6 +266,7 @@ def generator(): nonlocal usage_stats nonlocal accumulated_content nonlocal stop_reason + stream_error: Optional[BaseException] = None try: for chunk in response: # Extract usage stats from chunk @@ -288,6 +289,9 @@ def generator(): yield chunk + except Exception as exc: + stream_error = exc + raise finally: end_time = time.time() latency = end_time - start_time @@ -305,6 +309,7 @@ def generator(): latency, accumulated_content, stop_reason=stop_reason, + error=stream_error, ) return generator() diff --git a/posthog/ai/gemini/gemini_async.py b/posthog/ai/gemini/gemini_async.py index 7dc11fcd2..6156faf4a 100644 --- a/posthog/ai/gemini/gemini_async.py +++ b/posthog/ai/gemini/gemini_async.py @@ -253,6 +253,7 @@ async def async_generator(): nonlocal accumulated_content nonlocal stop_reason + stream_error: Optional[BaseException] = None try: async for chunk in response: # Extract usage stats from chunk @@ -275,6 +276,9 @@ async def async_generator(): yield chunk + except Exception as exc: + stream_error = exc + raise finally: end_time = time.time() latency = end_time - start_time @@ -292,6 +296,7 @@ async def async_generator(): latency, accumulated_content, stop_reason=stop_reason, + error=stream_error, ) return AsyncStreamWrapper(async_generator(), stream=response) diff --git a/posthog/ai/openai/_streaming.py b/posthog/ai/openai/_streaming.py index 2ee95ec91..376372687 100644 --- a/posthog/ai/openai/_streaming.py +++ b/posthog/ai/openai/_streaming.py @@ -102,6 +102,7 @@ def _build_streaming_event_data( model_from_response: Optional[str], stop_reason: Optional[str], service_tier: Optional[str] = None, + error: Optional[BaseException] = None, ) -> StreamingEventData: """Build the fields shared by both OpenAI streaming endpoint events.""" @@ -121,4 +122,5 @@ def _build_streaming_event_data( groups=groups, stop_reason=stop_reason, service_tier=service_tier, + error=error, ) diff --git a/posthog/ai/openai/openai.py b/posthog/ai/openai/openai.py index 0a8da0e58..9a0bca4a1 100644 --- a/posthog/ai/openai/openai.py +++ b/posthog/ai/openai/openai.py @@ -170,10 +170,14 @@ def _create_streaming( response = self._original.create(**kwargs) def generator(): + stream_error: Optional[BaseException] = None try: for chunk in response: state.process_chunk(chunk) yield chunk + except Exception as exc: + stream_error = exc + raise finally: self._capture_streaming_event( posthog_distinct_id, @@ -184,6 +188,7 @@ def generator(): kwargs, state, time.time() - start_time, + error=stream_error, ) return _StreamWrapper(generator(), stream=response) @@ -198,6 +203,7 @@ def _capture_streaming_event( kwargs: Dict[str, Any], state: _ResponsesStreamState, latency: float, + error: Optional[BaseException] = None, ): from posthog.ai.utils import capture_streaming_event @@ -216,6 +222,7 @@ def _capture_streaming_event( model_from_response=state.model, stop_reason=state.stop_reason, service_tier=state.service_tier, + error=error, ) capture_streaming_event(self._client._ph_client, event_data) @@ -388,10 +395,14 @@ def _create_streaming( response = self._original.create(**kwargs) def generator(): + stream_error: Optional[BaseException] = None try: for chunk in response: state.process_chunk(chunk) yield chunk + except Exception as exc: + stream_error = exc + raise finally: self._capture_streaming_event( posthog_distinct_id, @@ -402,6 +413,7 @@ def generator(): kwargs, state, time.time() - start_time, + error=stream_error, ) return _StreamWrapper(generator(), stream=response) @@ -416,6 +428,7 @@ def _capture_streaming_event( kwargs: Dict[str, Any], state: _ChatCompletionsStreamState, latency: float, + error: Optional[BaseException] = None, ): from posthog.ai.utils import capture_streaming_event @@ -436,6 +449,7 @@ def _capture_streaming_event( model_from_response=state.model, stop_reason=state.stop_reason, service_tier=state.service_tier, + error=error, ) capture_streaming_event(self._client._ph_client, event_data) diff --git a/posthog/ai/openai/openai_async.py b/posthog/ai/openai/openai_async.py index f9e574c4f..352f71500 100644 --- a/posthog/ai/openai/openai_async.py +++ b/posthog/ai/openai/openai_async.py @@ -171,10 +171,14 @@ async def _create_streaming( response = await self._original.create(**kwargs) async def async_generator(): + stream_error: Optional[BaseException] = None try: async for chunk in response: state.process_chunk(chunk) yield chunk + except Exception as exc: + stream_error = exc + raise finally: await self._capture_streaming_event( posthog_distinct_id, @@ -185,6 +189,7 @@ async def async_generator(): kwargs, state, time.time() - start_time, + error=stream_error, ) return AsyncStreamWrapper(async_generator(), stream=response) @@ -199,6 +204,7 @@ async def _capture_streaming_event( kwargs: Dict[str, Any], state: _ResponsesStreamState, latency: float, + error: Optional[BaseException] = None, ): from posthog.ai.utils import capture_streaming_event @@ -217,6 +223,7 @@ async def _capture_streaming_event( model_from_response=state.model, stop_reason=state.stop_reason, service_tier=state.service_tier, + error=error, ) capture_streaming_event(self._client._ph_client, event_data) @@ -392,10 +399,14 @@ async def _create_streaming( response = await self._original.create(**kwargs) async def async_generator(): + stream_error: Optional[BaseException] = None try: async for chunk in response: state.process_chunk(chunk) yield chunk + except Exception as exc: + stream_error = exc + raise finally: await self._capture_streaming_event( posthog_distinct_id, @@ -406,6 +417,7 @@ async def async_generator(): kwargs, state, time.time() - start_time, + error=stream_error, ) return AsyncStreamWrapper(async_generator(), stream=response) @@ -420,6 +432,7 @@ async def _capture_streaming_event( kwargs: Dict[str, Any], state: _ChatCompletionsStreamState, latency: float, + error: Optional[BaseException] = None, ): from posthog.ai.utils import capture_streaming_event @@ -440,6 +453,7 @@ async def _capture_streaming_event( model_from_response=state.model, stop_reason=state.stop_reason, service_tier=state.service_tier, + error=error, ) capture_streaming_event(self._client._ph_client, event_data) diff --git a/posthog/ai/types.py b/posthog/ai/types.py index 36424b133..1fc5555fa 100644 --- a/posthog/ai/types.py +++ b/posthog/ai/types.py @@ -143,3 +143,4 @@ class StreamingEventData(TypedDict): groups: Optional[Dict[str, Any]] stop_reason: Optional[str] service_tier: NotRequired[Optional[str]] + error: NotRequired[Optional[BaseException]] # raised mid-stream, if any diff --git a/posthog/ai/utils.py b/posthog/ai/utils.py index e67ab2d21..bb1932423 100644 --- a/posthog/ai/utils.py +++ b/posthog/ai/utils.py @@ -868,6 +868,7 @@ def capture_streaming_event( event_data: Standardized streaming event data containing all necessary information """ trace_id = event_data.get("trace_id") or str(uuid.uuid4()) + error = event_data.get("error") # Omitted when the provider never reported a count: absent means unknown, # 0 is a report of nothing. An interrupted stream often reports neither. @@ -896,13 +897,18 @@ def capture_streaming_event( event_data["privacy_mode"], finalize_ai_content(event_data["formatted_output"], ph_client), ), - "$ai_http_status": 200, + "$ai_http_status": ( + getattr(error, "status_code", 0) if error is not None else 200 + ), **({"$ai_input_tokens": input_tokens} if input_tokens is not None else {}), **({"$ai_output_tokens": output_tokens} if output_tokens is not None else {}), "$ai_latency": event_data["latency"], "$ai_trace_id": trace_id, "$ai_base_url": str(event_data["base_url"]), **(event_data.get("properties") or {}), + **( + {"$ai_is_error": True, "$ai_error": str(error)} if error is not None else {} + ), } warn_if_posthog_ai_gateway(event_data["base_url"]) diff --git a/posthog/test/ai/test_stream_midstream_error.py b/posthog/test/ai/test_stream_midstream_error.py new file mode 100644 index 000000000..2355ba205 --- /dev/null +++ b/posthog/test/ai/test_stream_midstream_error.py @@ -0,0 +1,269 @@ +"""A stream that raises mid-flight must be captured as an error, not as a 200.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest + +from posthog.ai.types import StreamingEventData +from posthog.ai.utils import capture_streaming_event + + +@pytest.fixture +def mock_client(): + with patch("posthog.client.Client") as mock_client: + mock_client.privacy_mode = False + yield mock_client + + +def _props(mock_client): + assert mock_client.capture_ai.call_count == 1 + return mock_client.capture_ai.call_args[1]["properties"] + + +class _StatusError(RuntimeError): + status_code = 529 + + +def _event_data(**overrides) -> StreamingEventData: + data = StreamingEventData( + provider="openai", + model="gpt-4", + base_url="https://api.openai.com/v1", + kwargs={}, + formatted_input=[], + formatted_output=[], + usage_stats={}, + latency=0.1, + distinct_id="id", + trace_id="trace", + properties=None, + privacy_mode=False, + groups=None, + stop_reason=None, + ) + data.update(overrides) + return data + + +def test_capture_streaming_event_without_error_is_ok(mock_client): + capture_streaming_event(mock_client, _event_data()) + props = _props(mock_client) + assert props["$ai_http_status"] == 200 + assert "$ai_is_error" not in props + + +@pytest.mark.parametrize( + "error, status", [(RuntimeError("boom"), 0), (_StatusError("overloaded"), 529)] +) +def test_capture_streaming_event_with_error(mock_client, error, status): + capture_streaming_event(mock_client, _event_data(error=error)) + props = _props(mock_client) + assert props["$ai_http_status"] == status + assert props["$ai_is_error"] is True + assert props["$ai_error"] == str(error) + + +def test_openai_chat_stream_error(mock_client): + from openai.types.chat import ChatCompletionChunk + from openai.types.chat.chat_completion_chunk import Choice, ChoiceDelta + + from posthog.ai.openai import OpenAI + + chunk = ChatCompletionChunk( + id="c1", + created=1, + model="gpt-4", + object="chat.completion.chunk", + choices=[Choice(index=0, delta=ChoiceDelta(content="partial"))], + ) + + def stream(): + yield chunk + raise RuntimeError("connection reset") + + with patch("openai.resources.chat.completions.Completions.create") as create: + create.return_value = stream() + client = OpenAI(api_key="k", posthog_client=mock_client) + with pytest.raises(RuntimeError, match="connection reset"): + list( + client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": "hi"}], + stream=True, + ) + ) + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "connection reset" + assert props["$ai_http_status"] == 0 + + +@pytest.mark.asyncio +async def test_openai_chat_stream_error_async(mock_client): + from openai.types.chat import ChatCompletionChunk + from openai.types.chat.chat_completion_chunk import Choice, ChoiceDelta + + from posthog.ai.openai import AsyncOpenAI + + chunk = ChatCompletionChunk( + id="c1", + created=1, + model="gpt-4", + object="chat.completion.chunk", + choices=[Choice(index=0, delta=ChoiceDelta(content="partial"))], + ) + + async def stream(): + yield chunk + raise RuntimeError("connection reset") + + async def create(self, **kwargs): + return stream() + + with patch("openai.resources.chat.completions.AsyncCompletions.create", new=create): + client = AsyncOpenAI(api_key="k", posthog_client=mock_client) + response = await client.chat.completions.create( + model="gpt-4", messages=[{"role": "user", "content": "hi"}], stream=True + ) + with pytest.raises(RuntimeError, match="connection reset"): + async for _ in response: + pass + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_http_status"] == 0 + + +def test_openai_responses_stream_error(mock_client): + from posthog.ai.openai import OpenAI + + def stream(): + yield MagicMock(type="response.created", response=None) + raise RuntimeError("connection reset") + + with patch("openai.resources.responses.Responses.create") as create: + create.return_value = stream() + client = OpenAI(api_key="k", posthog_client=mock_client) + with pytest.raises(RuntimeError, match="connection reset"): + list(client.responses.create(model="gpt-4", input="hi", stream=True)) + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "connection reset" + + +def test_anthropic_stream_error(mock_client): + from posthog.ai.anthropic import Anthropic + + def stream(): + yield MagicMock(type="message_start", message=None) + raise _StatusError("overloaded") + + with patch("anthropic.resources.messages.Messages.create") as create: + create.return_value = stream() + client = Anthropic(api_key="k", posthog_client=mock_client) + with pytest.raises(_StatusError): + list( + client.messages.create( + model="claude-3-opus-20240229", + messages=[{"role": "user", "content": "hi"}], + max_tokens=5, + stream=True, + ) + ) + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_http_status"] == 529 + + +@pytest.mark.asyncio +async def test_anthropic_stream_error_async(mock_client): + from posthog.ai.anthropic import AsyncAnthropic + + async def stream(): + yield MagicMock(type="message_start", message=None) + raise _StatusError("overloaded") + + async def create(**kwargs): + return stream() + + with patch("anthropic.resources.messages.AsyncMessages.create", side_effect=create): + client = AsyncAnthropic(api_key="k", posthog_client=mock_client) + response = await client.messages.create( + model="claude-3-opus-20240229", + messages=[{"role": "user", "content": "hi"}], + max_tokens=5, + stream=True, + ) + with pytest.raises(_StatusError): + async for _ in response: + pass + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_http_status"] == 529 + + +def _gemini_chunk(): + chunk = MagicMock() + chunk.text = "partial" + chunk.usage_metadata = None + return chunk + + +def test_gemini_stream_error(mock_client): + pytest.importorskip("google.genai") + from google import genai as google_genai + + from posthog.ai.gemini import Client + + def stream(): + yield _gemini_chunk() + raise RuntimeError("503 overloaded mid-stream") + + with patch.object(google_genai, "Client") as cls: + inst = MagicMock() + cls.return_value = inst + inst.models.generate_content_stream.return_value = stream() + client = Client(api_key="k", posthog_client=mock_client) + with pytest.raises(RuntimeError, match="503"): + list( + client.models.generate_content_stream( + model="gemini-2.0-flash", contents=["hi"] + ) + ) + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_error"] == "503 overloaded mid-stream" + assert props["$ai_http_status"] == 0 + + +@pytest.mark.asyncio +async def test_gemini_stream_error_async(mock_client): + pytest.importorskip("google.genai") + from google import genai as google_genai + + from posthog.ai.gemini import AsyncClient + + async def stream(): + yield _gemini_chunk() + raise RuntimeError("503 overloaded mid-stream") + + with patch.object(google_genai, "Client") as cls: + inst = MagicMock() + cls.return_value = inst + inst.aio.models.generate_content_stream = AsyncMock(return_value=stream()) + client = AsyncClient(api_key="k", posthog_client=mock_client) + response = await client.models.generate_content_stream( + model="gemini-2.0-flash", contents=["hi"] + ) + with pytest.raises(RuntimeError, match="503"): + async for _ in response: + pass + + props = _props(mock_client) + assert props["$ai_is_error"] is True + assert props["$ai_http_status"] == 0 diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index 91f67d92b..ef58566bb 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -666,6 +666,7 @@ attribute posthog.ai.types.StreamingContentBlock.thinking: Optional[str] attribute posthog.ai.types.StreamingContentBlock.type: str attribute posthog.ai.types.StreamingEventData.base_url: str attribute posthog.ai.types.StreamingEventData.distinct_id: Optional[str] +attribute posthog.ai.types.StreamingEventData.error: NotRequired[Optional[BaseException]] attribute posthog.ai.types.StreamingEventData.formatted_input: Any attribute posthog.ai.types.StreamingEventData.formatted_output: Any attribute posthog.ai.types.StreamingEventData.groups: Optional[Dict[str, Any]] From be6ee29d8c0665228a8810e28d02a7dcb98a2771 Mon Sep 17 00:00:00 2001 From: alexcastgonz <82875882+pcbeingused333@users.noreply.github.com> Date: Thu, 22 Oct 2026 06:17:28 -0400 Subject: [PATCH 55/70] fix(ai): keep the refusal of a non-streamed OpenAI chat completion in the captured output (#1095) Co-authored-by: Claude Sonnet 5.5 (cherry picked from commit 42c8b7bc1ba1b1acca1b931830ded4818b26df33) --- .../changesets/openai-chat-refusal-output.md | 5 +++ posthog/ai/openai/openai_converter.py | 5 +++ .../test/ai/openai/test_openai_converter.py | 31 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 .sampo/changesets/openai-chat-refusal-output.md diff --git a/.sampo/changesets/openai-chat-refusal-output.md b/.sampo/changesets/openai-chat-refusal-output.md new file mode 100644 index 000000000..4d222d4d2 --- /dev/null +++ b/.sampo/changesets/openai-chat-refusal-output.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +A non-streamed OpenAI chat completion that the model refused is no longer captured with an empty `$ai_output_choices`: the refusal text is recorded as a `refusal` content block, as it already is for streamed responses. diff --git a/posthog/ai/openai/openai_converter.py b/posthog/ai/openai/openai_converter.py index 21c58478b..e0f397ff6 100644 --- a/posthog/ai/openai/openai_converter.py +++ b/posthog/ai/openai/openai_converter.py @@ -151,6 +151,11 @@ def format_openai_response(response: Any) -> List[FormattedMessage]: } ) + # A refused request carries its text in `refusal` and leaves `content` empty + refusal = getattr(choice.message, "refusal", None) + if refusal: + content.append({"type": "refusal", "refusal": refusal}) + if hasattr(choice.message, "tool_calls") and choice.message.tool_calls: for tool_call in choice.message.tool_calls: # Custom tools carry their free-form text in `custom.input`, diff --git a/posthog/test/ai/openai/test_openai_converter.py b/posthog/test/ai/openai/test_openai_converter.py index e23ecac87..a6ee44e6b 100644 --- a/posthog/test/ai/openai/test_openai_converter.py +++ b/posthog/test/ai/openai/test_openai_converter.py @@ -82,6 +82,37 @@ def test_message_object_does_not_crash(): assert out[1]["content"] == "hello" +def test_chat_response_keeps_refusal(): + """A refused chat completion has no content, only message.refusal, and used to be captured as [].""" + from openai.types.chat import ChatCompletion + from openai.types.chat.chat_completion import Choice + + from posthog.ai.openai.openai_converter import format_openai_response + + response = ChatCompletion( + id="chatcmpl-1", + object="chat.completion", + created=0, + model="gpt-4o", + choices=[ + Choice( + index=0, + finish_reason="stop", + message=ChatCompletionMessage( + role="assistant", content=None, refusal="I can't help with that" + ), + ) + ], + ) + + assert format_openai_response(response) == [ + { + "role": "assistant", + "content": [{"type": "refusal", "refusal": "I can't help with that"}], + } + ] + + def test_responses_output_keeps_all_items(): from posthog.ai.openai.openai_converter import format_openai_response From 62798117335872c5c1f133738304490c764c76bd Mon Sep 17 00:00:00 2001 From: alexcastgonz <82875882+pcbeingused333@users.noreply.github.com> Date: Thu, 22 Oct 2026 06:18:07 -0400 Subject: [PATCH 56/70] fix(ai): record an integer $ai_http_status in the LangChain callback handler (#1096) Co-authored-by: Claude Sonnet 5.5 (cherry picked from commit a6ddc2ed3227a1f8efa170f3eb7fce5b9aef36db) --- .../changesets/langchain-http-status-int.md | 5 ++ posthog/ai/langchain/callbacks.py | 8 ++- posthog/test/ai/langchain/test_callbacks.py | 61 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 .sampo/changesets/langchain-http-status-int.md diff --git a/.sampo/changesets/langchain-http-status-int.md b/.sampo/changesets/langchain-http-status-int.md new file mode 100644 index 000000000..37e2f623c --- /dev/null +++ b/.sampo/changesets/langchain-http-status-int.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +The LangChain callback handler now records `$ai_http_status` as an integer for failed generations. An error that carries a string `code` and no status code (such as OpenAI's `rate_limit_exceeded`) gave a string status; it now gives `0`, as an error without a status already did. diff --git a/posthog/ai/langchain/callbacks.py b/posthog/ai/langchain/callbacks.py index 103f39e35..da46718f3 100644 --- a/posthog/ai/langchain/callbacks.py +++ b/posthog/ai/langchain/callbacks.py @@ -1032,8 +1032,12 @@ def _get_http_status(error: BaseException) -> int: # OpenAI: https://github.com/openai/openai-python/blob/main/src/openai/_exceptions.py # Anthropic: https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_exceptions.py # Google: https://github.com/googleapis/python-api-core/blob/main/google/api_core/exceptions.py - status_code = getattr(error, "status_code", getattr(error, "code", 0)) - return status_code + # `code` is a string on some errors (OpenAI's "rate_limit_exceeded"), so only ints count + for attribute in ("status_code", "code"): + value = getattr(error, attribute, None) + if isinstance(value, int) and not isinstance(value, bool): + return value + return 0 def _get_langchain_run_name( diff --git a/posthog/test/ai/langchain/test_callbacks.py b/posthog/test/ai/langchain/test_callbacks.py index 32c9f1e3d..e55c42bb7 100644 --- a/posthog/test/ai/langchain/test_callbacks.py +++ b/posthog/test/ai/langchain/test_callbacks.py @@ -2939,3 +2939,64 @@ def test_stop_reason_resolution( props = mock_client.capture_ai.call_args.kwargs["properties"] assert props.get("$ai_stop_reason") == expected + + +class TestGetHttpStatus: + def test_uses_the_status_code_of_an_http_error(self): + from posthog.ai.langchain.callbacks import _get_http_status + + error = Exception("rate limited") + error.status_code = 429 # type: ignore[attr-defined] + + assert _get_http_status(error) == 429 + + def test_uses_an_integer_code_when_there_is_no_status_code(self): + from posthog.ai.langchain.callbacks import _get_http_status + + error = Exception("quota") + error.code = 503 # type: ignore[attr-defined] + + assert _get_http_status(error) == 503 + + def test_ignores_a_string_code(self): + """OpenAI's APIError carries code="rate_limit_exceeded" and no status code.""" + from posthog.ai.langchain.callbacks import _get_http_status + + error = Exception("Rate limit reached") + error.code = "rate_limit_exceeded" # type: ignore[attr-defined] + + assert _get_http_status(error) == 0 + + def test_falls_back_to_zero_without_a_status(self): + from posthog.ai.langchain.callbacks import _get_http_status + + assert _get_http_status(Exception("boom")) == 0 + + def test_an_error_event_records_an_integer_status(self): + import httpx + import openai + from unittest.mock import MagicMock + from uuid import uuid4 + + from posthog.ai.langchain import CallbackHandler + + client = MagicMock() + client.privacy_mode = False + callback = CallbackHandler(client) + run_id = uuid4() + callback._set_llm_metadata( + serialized={}, + run_id=run_id, + messages=[{"role": "user", "content": "test"}], + metadata={"ls_provider": "openai", "ls_model_name": "gpt-5.6-sol"}, + ) + error = openai.APIError( + "Rate limit reached", + request=httpx.Request("POST", "https://api.openai.com/v1/chat/completions"), + body={"code": "rate_limit_exceeded", "message": "Rate limit reached"}, + ) + + callback._pop_run_and_capture_generation(run_id, None, error) + + properties = client.capture_ai.call_args_list[0][1]["properties"] + assert properties["$ai_http_status"] == 0 From 88f08d970ad4fcc45736d03a6ba7af337cc8bbcb Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:21:18 +0000 Subject: [PATCH 57/70] chore: Release v7.75.3 [skip ci] (cherry picked from commit dc0126690696694809d3c5ff3785f142c509e4fb) --- .sampo/changesets/langchain-http-status-int.md | 5 ----- .sampo/changesets/openai-chat-refusal-output.md | 5 ----- .sampo/changesets/streaming-midstream-error.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 8 ++++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 9 files changed, 19 insertions(+), 20 deletions(-) delete mode 100644 .sampo/changesets/langchain-http-status-int.md delete mode 100644 .sampo/changesets/openai-chat-refusal-output.md delete mode 100644 .sampo/changesets/streaming-midstream-error.md diff --git a/.sampo/changesets/langchain-http-status-int.md b/.sampo/changesets/langchain-http-status-int.md deleted file mode 100644 index 37e2f623c..000000000 --- a/.sampo/changesets/langchain-http-status-int.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -The LangChain callback handler now records `$ai_http_status` as an integer for failed generations. An error that carries a string `code` and no status code (such as OpenAI's `rate_limit_exceeded`) gave a string status; it now gives `0`, as an error without a status already did. diff --git a/.sampo/changesets/openai-chat-refusal-output.md b/.sampo/changesets/openai-chat-refusal-output.md deleted file mode 100644 index 4d222d4d2..000000000 --- a/.sampo/changesets/openai-chat-refusal-output.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -A non-streamed OpenAI chat completion that the model refused is no longer captured with an empty `$ai_output_choices`: the refusal text is recorded as a `refusal` content block, as it already is for streamed responses. diff --git a/.sampo/changesets/streaming-midstream-error.md b/.sampo/changesets/streaming-midstream-error.md deleted file mode 100644 index b66920190..000000000 --- a/.sampo/changesets/streaming-midstream-error.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Streamed OpenAI, Anthropic and Gemini generations that raise mid-stream are now captured with `$ai_is_error` and `$ai_error` (and the error's status code as `$ai_http_status`) instead of being recorded as a successful 200. The error is still re-raised to the caller, matching what non-streaming calls already did. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 9e72ba64b..4672bcd96 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.117 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.3 + ## 0.1.116 — 2026-10-22 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 5fa1a76ca..211aafdbb 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.116" +version = "0.1.117" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 8f249b1a0..78146af1b 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,13 @@ # posthog +## 7.75.3 — 2026-10-22 + +### Patch changes + +- [a6ddc2e](https://github.com/posthog/posthog-python/commit/a6ddc2ed3227a1f8efa170f3eb7fce5b9aef36db) The LangChain callback handler now records `$ai_http_status` as an integer for failed generations. An error that carries a string `code` and no status code (such as OpenAI's `rate_limit_exceeded`) gave a string status; it now gives `0`, as an error without a status already did. — Thanks @pcbeingused333 for your first contribution 🎉! +- [42c8b7b](https://github.com/posthog/posthog-python/commit/42c8b7bc1ba1b1acca1b931830ded4818b26df33) A non-streamed OpenAI chat completion that the model refused is no longer captured with an empty `$ai_output_choices`: the refusal text is recorded as a `refusal` content block, as it already is for streamed responses. — Thanks @pcbeingused333 for your first contribution 🎉! +- [dc2a2b4](https://github.com/posthog/posthog-python/commit/dc2a2b4e33659e7909786fa48c625d37dc4da94d) Streamed OpenAI, Anthropic and Gemini generations that raise mid-stream are now captured with `$ai_is_error` and `$ai_error` (and the error's status code as `$ai_http_status`) instead of being recorded as a successful 200. The error is still re-raised to the caller, matching what non-streaming calls already did. — Thanks @pcbeingused333 for your first contribution 🎉! + ## 7.75.2 — 2026-10-22 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index 1f9f0be5a..c05dfc087 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.2" +VERSION = "7.75.3" diff --git a/pyproject.toml b/pyproject.toml index 463ca4618..1f86bbd4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.2" +version = "7.75.3" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index bab629ad0..389dd103f 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.116" +version = "0.1.117" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.2" +version = "7.75.3" source = { editable = "." } dependencies = [ { name = "distro" }, From e799a0aa95ec29c0f0f46a3a14f7edf63582437b Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:21:23 +0000 Subject: [PATCH 58/70] Update generated references (cherry picked from commit 9185524005c394e78a977092dcf9fcb7885160dc) --- .../posthog-python-references-7.75.3.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.3.json diff --git a/references/posthog-python-references-7.75.3.json b/references/posthog-python-references-7.75.3.json new file mode 100644 index 000000000..03f87f17f --- /dev/null +++ b/references/posthog-python-references-7.75.3.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.3", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 6b0cdcdf1..03f87f17f 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.2", + "version": "7.75.3", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From 972fc1de6345cc850bba6b999db93ac235ccd3bb Mon Sep 17 00:00:00 2001 From: Harsh Kashyap <55448981+Harsh23Kashyap@users.noreply.github.com> Date: Thu, 22 Oct 2026 16:00:08 +0530 Subject: [PATCH 59/70] fix(ai): keep latest cumulative output tokens across message_deltas (#1100) * fix(ai): keep latest cumulative output tokens across message_deltas Server tools such as web search can emit several message_delta events in one Anthropic stream, and each delta's usage is cumulative. The stream accumulator added every delta's output_tokens together, so a stream with two deltas reporting 50 then 110 cumulative tokens captured 160. Keep the latest cumulative value, matching how the input and cache counts are already handled and how the Anthropic SDK accumulates usage. * style(ai): format cumulative token async regression test --------- Co-authored-by: Manoel Aranda Neto (cherry picked from commit 34ec4f828a45728c91e452e960aa0119a3052812) --- .../cumulative-delta-output-tokens.md | 5 ++ posthog/ai/anthropic/_anthropic_stream.py | 10 ++- posthog/test/ai/anthropic/test_anthropic.py | 81 +++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 .sampo/changesets/cumulative-delta-output-tokens.md diff --git a/.sampo/changesets/cumulative-delta-output-tokens.md b/.sampo/changesets/cumulative-delta-output-tokens.md new file mode 100644 index 000000000..cbc8bc720 --- /dev/null +++ b/.sampo/changesets/cumulative-delta-output-tokens.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Streamed Anthropic generations no longer stack output tokens when a stream emits more than one `message_delta` (server tools can send several). Each delta's usage is cumulative, so the accumulator now keeps the latest total instead of adding every delta together. diff --git a/posthog/ai/anthropic/_anthropic_stream.py b/posthog/ai/anthropic/_anthropic_stream.py index ff3fbe0b8..2df160ef8 100644 --- a/posthog/ai/anthropic/_anthropic_stream.py +++ b/posthog/ai/anthropic/_anthropic_stream.py @@ -53,7 +53,15 @@ def consume(self, event: Any) -> None: event_usage = extract_anthropic_usage_from_event(event) merge_usage_stats(self.usage_stats, event_usage) if getattr(event, "type", None) == "message_delta": - self._apply_cumulative_input_usage(getattr(event, "usage", None)) + usage = getattr(event, "usage", None) + self._apply_cumulative_input_usage(usage) + output_tokens = getattr(usage, "output_tokens", None) + if isinstance(output_tokens, int) and not isinstance(output_tokens, bool): + # output_tokens on a message_delta is cumulative too, so the + # incremental merge above must not stack successive deltas + # (server tools can emit several in one stream). Keep the + # latest total; a field the event omits leaves the prior one. + self.usage_stats["output_tokens"] = output_tokens if getattr(event, "type", None) == "content_block_start": block, tool = handle_anthropic_content_block_start(event) diff --git a/posthog/test/ai/anthropic/test_anthropic.py b/posthog/test/ai/anthropic/test_anthropic.py index 13fbccd65..3eb7d75ac 100644 --- a/posthog/test/ai/anthropic/test_anthropic.py +++ b/posthog/test/ai/anthropic/test_anthropic.py @@ -907,6 +907,87 @@ async def mock_async_create(**kwargs): assert_cumulative_delta_usage(mock_client.capture_ai.call_args.kwargs["properties"]) +def anthropic_stream_with_two_cumulative_deltas(): + # Server tools can emit more than one message_delta in a single stream, + # and each delta's usage is cumulative: later values replace earlier ones + # rather than adding to them. + return [ + RawMessageStartEvent( + type="message_start", + message=Message( + id="msg_1", + type="message", + role="assistant", + model="claude-haiku-4-5", + content=[], + stop_reason=None, + stop_sequence=None, + usage=Usage( + input_tokens=100, + output_tokens=1, + cache_creation_input_tokens=0, + cache_read_input_tokens=0, + ), + ), + ), + RawMessageDeltaEvent( + type="message_delta", + delta=Delta(stop_reason="pause_turn", stop_sequence=None), + usage=MessageDeltaUsage(output_tokens=50), + ), + RawMessageDeltaEvent( + type="message_delta", + delta=Delta(stop_reason="end_turn", stop_sequence=None), + usage=MessageDeltaUsage(output_tokens=110), + ), + RawMessageStopEvent(type="message_stop"), + ] + + +def test_streaming_multiple_message_deltas_do_not_stack_output_tokens(mock_client): + with patch( + "anthropic.resources.Messages.create", + return_value=iter(anthropic_stream_with_two_cumulative_deltas()), + ): + client = Anthropic(api_key="test-key", posthog_client=mock_client) + response = client.messages.create( + model="claude-haiku-4-5", + messages=[{"role": "user", "content": "Hello"}], + stream=True, + ) + list(response) + + props = mock_client.capture_ai.call_args.kwargs["properties"] + assert props["$ai_output_tokens"] == 110 + + +@pytest.mark.asyncio +async def test_streaming_multiple_message_deltas_do_not_stack_output_tokens_async( + mock_client, +): + async def mock_async_stream(): + for event in anthropic_stream_with_two_cumulative_deltas(): + yield event + + async def mock_async_create(**kwargs): + return mock_async_stream() + + with patch( + "anthropic.resources.messages.AsyncMessages.create", + side_effect=mock_async_create, + ): + client = AsyncAnthropic(api_key="test-key", posthog_client=mock_client) + response = await client.messages.create( + model="claude-haiku-4-5", + messages=[{"role": "user", "content": "Hello"}], + stream=True, + ) + [event async for event in response] + + props = mock_client.capture_ai.call_args.kwargs["properties"] + assert props["$ai_output_tokens"] == 110 + + def test_anthropic_bedrock_preserves_cache_creation_ttl_breakdown( mock_client, mock_anthropic_response_with_cache_ttl ): From 398581bd775c113e9a9af1b0b3f0e931b782dcff Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:39:43 +0000 Subject: [PATCH 60/70] chore: Release v7.75.4 [skip ci] (cherry picked from commit 84664b48304ff81c68ae5ed0a92e938a27d22a46) --- .sampo/changesets/cumulative-delta-output-tokens.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/cumulative-delta-output-tokens.md diff --git a/.sampo/changesets/cumulative-delta-output-tokens.md b/.sampo/changesets/cumulative-delta-output-tokens.md deleted file mode 100644 index cbc8bc720..000000000 --- a/.sampo/changesets/cumulative-delta-output-tokens.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Streamed Anthropic generations no longer stack output tokens when a stream emits more than one `message_delta` (server tools can send several). Each delta's usage is cumulative, so the accumulator now keeps the latest total instead of adding every delta together. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 4672bcd96..72530f8c3 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.118 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.4 + ## 0.1.117 — 2026-10-22 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 211aafdbb..d2a95571e 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.117" +version = "0.1.118" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 78146af1b..db223afe4 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.75.4 — 2026-10-22 + +### Patch changes + +- [34ec4f8](https://github.com/posthog/posthog-python/commit/34ec4f828a45728c91e452e960aa0119a3052812) Streamed Anthropic generations no longer stack output tokens when a stream emits more than one `message_delta` (server tools can send several). Each delta's usage is cumulative, so the accumulator now keeps the latest total instead of adding every delta together. — Thanks @Harsh23Kashyap! + ## 7.75.3 — 2026-10-22 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index c05dfc087..0c240c3d9 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.3" +VERSION = "7.75.4" diff --git a/pyproject.toml b/pyproject.toml index 1f86bbd4f..76c7cf5ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.3" +version = "7.75.4" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 389dd103f..883350e13 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.117" +version = "0.1.118" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.3" +version = "7.75.4" source = { editable = "." } dependencies = [ { name = "distro" }, From 8e973634f30c8013a9f4913ca8ef5512ad001114 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:39:48 +0000 Subject: [PATCH 61/70] Update generated references (cherry picked from commit e17a8bed922739c67bfbadd55d0c8ec9aab9ac2e) --- .../posthog-python-references-7.75.4.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.4.json diff --git a/references/posthog-python-references-7.75.4.json b/references/posthog-python-references-7.75.4.json new file mode 100644 index 000000000..2cd75278e --- /dev/null +++ b/references/posthog-python-references-7.75.4.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.4", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "int" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "int" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 03f87f17f..2cd75278e 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.3", + "version": "7.75.4", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From da41fbe9ca7233d1150fa5a5c28e3e6ae5644f2b Mon Sep 17 00:00:00 2001 From: Harsh Kashyap <55448981+Harsh23Kashyap@users.noreply.github.com> Date: Thu, 22 Oct 2026 19:56:56 +0530 Subject: [PATCH 62/70] fix: serialize non-finite floats as null in JSON payloads (#1081) * fix: serialize non-finite floats as null in JSON payloads Added a helper function to replace non-finite floats with None in JSON serialization. * test: cover non-finite float serialization in batch payloads * chore: refresh public API snapshot for DatetimeSerializer.encode (cherry picked from commit 18b39e895a45eed0e078c97848c03d0f066b3287) --- posthog/request.py | 21 ++++++++++++++++ posthog/test/test_request.py | 40 ++++++++++++++++++++++++++++++ references/public_api_snapshot.txt | 1 + 3 files changed, 62 insertions(+) diff --git a/posthog/request.py b/posthog/request.py index f23e40e31..e1e35503d 100644 --- a/posthog/request.py +++ b/posthog/request.py @@ -1,5 +1,6 @@ import json import logging +import math import re import socket import time @@ -414,9 +415,29 @@ class QuotaLimitError(APIError): RequestsConnectionError = requests.exceptions.ConnectionError +def _replace_non_finite_floats(value: Any) -> Any: + """Recursively replace inf/nan floats with None. + + json.dumps with the default allow_nan=True emits bare Infinity/NaN tokens, + which are not valid JSON and get rejected by strict-parsing ingestion (and + intermediaries). posthog-js avoids this because JSON.stringify converts + non-finite numbers to null; this mirrors that behavior. + """ + if isinstance(value, float): + return value if math.isfinite(value) else None + if isinstance(value, dict): + return {key: _replace_non_finite_floats(item) for key, item in value.items()} + if isinstance(value, (list, tuple)): + return [_replace_non_finite_floats(item) for item in value] + return value + + class DatetimeSerializer(json.JSONEncoder): def default(self, obj: Any): if isinstance(obj, (date, datetime)): return obj.isoformat() return json.JSONEncoder.default(self, obj) + + def encode(self, o: Any) -> str: + return super().encode(_replace_non_finite_floats(o)) diff --git a/posthog/test/test_request.py b/posthog/test/test_request.py index c16e08f47..1a253e8a5 100644 --- a/posthog/test/test_request.py +++ b/posthog/test/test_request.py @@ -660,3 +660,43 @@ def test_flags_does_not_retry_other_http_status_errors(self, status_code): self.assertEqual(cm.exception.status, status_code) self.assertEqual(mock_session.post.call_count, 1) + + +def test_post_serializes_non_finite_floats_as_null(): + mock_response = requests.Response() + mock_response.status_code = 200 + mock_session = mock.MagicMock() + mock_session.post.return_value = mock_response + + request_module.post( + TEST_API_KEY, + host="https://test.posthog.com", + path="/batch/", + session=mock_session, + batch=[ + { + "event": "score_computed", + "distinct_id": "user-1", + "properties": { + "score": float("inf"), + "nested": [float("nan"), {"depth": float("-inf")}], + "ok": 1.5, + }, + } + ], + ) + + raw = mock_session.post.call_args.kwargs["data"] + # Bare Infinity/NaN tokens are not valid JSON; a strict parser must accept the body. + data = json.loads( + raw, parse_constant=lambda x: (_ for _ in ()).throw(ValueError(x)) + ) + props = data["batch"][0]["properties"] + assert props["score"] is None + assert props["nested"] == [None, {"depth": None}] + assert props["ok"] == 1.5 + + +def test_datetime_serializer_keeps_finite_values(): + body = {"n": 1.5, "s": "x", "b": True, "i": 3, "none": None} + assert json.loads(json.dumps(body, cls=DatetimeSerializer)) == body diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index ef58566bb..24b12e7d1 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -1829,6 +1829,7 @@ method posthog.metrics_capture.PostHogMetrics.reset() -> None method posthog.poller.Poller.run() method posthog.poller.Poller.stop() method posthog.request.DatetimeSerializer.default(obj: Any) +method posthog.request.DatetimeSerializer.encode(o: Any) -> str method posthog.request.HTTPAdapterWithSocketOptions.init_poolmanager(*args, **kwargs) method posthog.tracing.span.Span.add_event(name: str, attributes: Optional[Mapping[str, Any]] = None, timestamp: Union[datetime, float, None] = None) -> Span method posthog.tracing.span.Span.end(end_time: Union[datetime, float, None] = None) -> None From 25dd7d580345b1e79e21b391c5089524019c1166 Mon Sep 17 00:00:00 2001 From: Anna Garcia <11654201+turnipdabeets@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:58:01 -0400 Subject: [PATCH 63/70] fix: annotate client timeouts as float (#1106) `timeout` and `feature_flags_request_timeout_seconds` were typed (or inferred) as `int`, so type checkers rejected fractional values even though they go straight to requests/httpx, which accept floats. Fixes #1089 Co-authored-by: Claude Opus 5.5 (1M context) (cherry picked from commit b3fcec639aa9c49514344ba97b24492f03e87b86) --- .sampo/changesets/float-timeout-annotations.md | 5 +++++ posthog/__init__.py | 2 +- posthog/_async_request.py | 4 ++-- posthog/async_client.py | 4 ++-- posthog/client.py | 4 ++-- posthog/consumer.py | 2 +- posthog/request.py | 8 ++++---- references/public_api_snapshot.txt | 14 +++++++------- typings/requests/__init__.pyi | 2 +- 9 files changed, 25 insertions(+), 20 deletions(-) create mode 100644 .sampo/changesets/float-timeout-annotations.md diff --git a/.sampo/changesets/float-timeout-annotations.md b/.sampo/changesets/float-timeout-annotations.md new file mode 100644 index 000000000..fd4222710 --- /dev/null +++ b/.sampo/changesets/float-timeout-annotations.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Annotate `timeout` and `feature_flags_request_timeout_seconds` as `float` on `Client`, `AsyncClient`, `Consumer` and the request helpers, so type checkers accept fractional timeouts such as `timeout=2.5`. The values were already passed straight to `requests` and `httpx`, which take floats, so runtime behaviour is unchanged. diff --git a/posthog/__init__.py b/posthog/__init__.py index 4b663db29..b5bea2600 100644 --- a/posthog/__init__.py +++ b/posthog/__init__.py @@ -469,7 +469,7 @@ def get_context_options() -> Dict[str, Any]: poll_interval = 30 # type: int disable_geoip = True # type: bool is_server = True # type: bool -feature_flags_request_timeout_seconds = 3 # type: int +feature_flags_request_timeout_seconds = 3 # type: float feature_flags_request_max_retries = 1 # type: int super_properties = None # type: Optional[Dict] super_options = None # type: Optional[Dict] diff --git a/posthog/_async_request.py b/posthog/_async_request.py index 1e10c3cd2..c45b9093d 100644 --- a/posthog/_async_request.py +++ b/posthog/_async_request.py @@ -80,7 +80,7 @@ async def async_flags( api_key: str, host: Optional[str], *, - timeout: int, + timeout: float, max_retries: int, client: Optional[Any] = None, **request_data: Any, @@ -123,7 +123,7 @@ async def async_remote_config( host: Optional[str], key: str, *, - timeout: int, + timeout: float, client: Optional[Any] = None, ) -> Any: """Fetch and decrypt one remote-config payload.""" diff --git a/posthog/async_client.py b/posthog/async_client.py index 87237a1b6..d13f0ff52 100644 --- a/posthog/async_client.py +++ b/posthog/async_client.py @@ -139,7 +139,7 @@ def __init__( flush_at: int = 100, flush_interval: float = 5.0, max_retries: int = 3, - timeout: int = 15, + timeout: float = 15, thread: int = 1, disabled: bool = False, disable_geoip: bool = True, @@ -166,7 +166,7 @@ def __init__( capture_trace_context: bool = False, secret_key: Optional[str] = None, personal_api_key: Optional[str] = None, - feature_flags_request_timeout_seconds: int = 3, + feature_flags_request_timeout_seconds: float = 3, feature_flags_request_max_retries: int = 1, ) -> None: if flush_at <= 0: diff --git a/posthog/client.py b/posthog/client.py index 556029f53..19744b9e5 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -740,7 +740,7 @@ def __init__( flush_interval=5.0, max_retries=3, sync_mode=False, - timeout=15, + timeout: float = 15, thread=1, poll_interval=30, personal_api_key=None, @@ -748,7 +748,7 @@ def __init__( disable_geoip=True, is_server=True, historical_migration=False, - feature_flags_request_timeout_seconds=3, + feature_flags_request_timeout_seconds: float = 3, feature_flags_request_max_retries=1, super_properties=None, super_options=None, diff --git a/posthog/consumer.py b/posthog/consumer.py index 1f9c9f316..265cb9e77 100644 --- a/posthog/consumer.py +++ b/posthog/consumer.py @@ -117,7 +117,7 @@ def __init__( on_error=None, flush_interval=5.0, retries=3, - timeout=15, + timeout: float = 15, historical_migration=False, endpoint=_CAPTURE_V1_PATH, max_msg_size=MAX_MSG_SIZE, diff --git a/posthog/request.py b/posthog/request.py index e1e35503d..ef73c7212 100644 --- a/posthog/request.py +++ b/posthog/request.py @@ -215,7 +215,7 @@ def post( host: Optional[str] = None, path: Optional[str] = None, *, - timeout: int = 15, + timeout: float = 15, session: Optional[requests.Session] = None, **kwargs, ) -> requests.Response: @@ -301,7 +301,7 @@ def flags( api_key: str, host: Optional[str] = None, *, - timeout: int = 15, + timeout: float = 15, max_retries: int = 1, **kwargs, ) -> Any: @@ -340,7 +340,7 @@ def remote_config( project_api_key: str, host: Optional[str] = None, key: str = "", - timeout: int = 15, + timeout: float = 15, ) -> Any: """Get remote config flag value from remote_config API endpoint""" response = get( @@ -356,7 +356,7 @@ def get( api_key: str, url: str, host: Optional[str] = None, - timeout: Optional[int] = None, + timeout: Optional[float] = None, etag: Optional[str] = None, ) -> GetResponse: """ diff --git a/references/public_api_snapshot.txt b/references/public_api_snapshot.txt index 24b12e7d1..977871ced 100644 --- a/references/public_api_snapshot.txt +++ b/references/public_api_snapshot.txt @@ -1263,14 +1263,14 @@ class posthog.ai.types.TokenUsage class posthog.ai.types.ToolInProgress class posthog.args.OptionalCaptureArgs class posthog.args.OptionalSetArgs -class posthog.async_client.AsyncClient(project_api_key: str, host: Optional[str] = None, *, debug: bool = False, max_queue_size: int = 10000, send: bool = True, on_error=None, flush_at: int = 100, flush_interval: float = 5.0, max_retries: int = 3, timeout: int = 15, thread: int = 1, disabled: bool = False, disable_geoip: bool = True, is_server: bool = True, historical_migration: bool = False, super_properties: Optional[dict[str, Any]] = None, super_options: Optional[dict[str, Any]] = None, before_send=None, log_captured_exceptions: bool = False, project_root: Optional[str] = None, capture_exception_code_variables: bool = False, code_variables_mask_patterns=None, code_variables_ignore_patterns=None, code_variables_mask_url_credentials=None, code_variables_detect_secrets=None, in_app_modules: Optional[list[str]] = None, capture_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_max_queue_size: int = 1000, capture_ai_timeout: float = 30, capture_ai_max_event_bytes: int = AI_MAX_MSG_SIZE, privacy_mode: bool = False, enable_full_ai_capture: bool = False, capture_trace_context: bool = False, secret_key: Optional[str] = None, personal_api_key: Optional[str] = None, feature_flags_request_timeout_seconds: int = 3, feature_flags_request_max_retries: int = 1) +class posthog.async_client.AsyncClient(project_api_key: str, host: Optional[str] = None, *, debug: bool = False, max_queue_size: int = 10000, send: bool = True, on_error=None, flush_at: int = 100, flush_interval: float = 5.0, max_retries: int = 3, timeout: float = 15, thread: int = 1, disabled: bool = False, disable_geoip: bool = True, is_server: bool = True, historical_migration: bool = False, super_properties: Optional[dict[str, Any]] = None, super_options: Optional[dict[str, Any]] = None, before_send=None, log_captured_exceptions: bool = False, project_root: Optional[str] = None, capture_exception_code_variables: bool = False, code_variables_mask_patterns=None, code_variables_ignore_patterns=None, code_variables_mask_url_credentials=None, code_variables_detect_secrets=None, in_app_modules: Optional[list[str]] = None, capture_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_max_queue_size: int = 1000, capture_ai_timeout: float = 30, capture_ai_max_event_bytes: int = AI_MAX_MSG_SIZE, privacy_mode: bool = False, enable_full_ai_capture: bool = False, capture_trace_context: bool = False, secret_key: Optional[str] = None, personal_api_key: Optional[str] = None, feature_flags_request_timeout_seconds: float = 3, feature_flags_request_max_retries: int = 1) class posthog.async_client.AsyncPosthog class posthog.bucketed_rate_limiter.BucketedRateLimiter(bucket_size: Number, refill_rate: Number, refill_interval_seconds: Number, on_bucket_rate_limited: Optional[Callable[[Hashable], None]] = None, clock: Callable[[], float] = time.monotonic) class posthog.capture_compression.CaptureCompression class posthog.capture_send.CaptureError(status: int | str, message: str, *, endpoint: str, retry_after: Optional[float] = None, request_id: Optional[str] = None, attempts: Optional[int] = None, retry_exhausted: Optional[list[str]] = None, drops: Optional[list[tuple[str, Optional[str]]]] = None, event_results: Optional[dict[str, CaptureEventResult]] = None) class posthog.capture_send.CaptureEventResult(result: Optional[str], details: Optional[str] = None) -class posthog.client.Client(project_api_key: str, host=None, *, debug=False, max_queue_size=10000, send=True, on_error=None, flush_at=100, flush_interval=5.0, max_retries=3, sync_mode=False, timeout=15, thread=1, poll_interval=30, personal_api_key=None, disabled=False, disable_geoip=True, is_server=True, historical_migration=False, feature_flags_request_timeout_seconds=3, feature_flags_request_max_retries=1, super_properties=None, super_options=None, enable_exception_autocapture=False, log_captured_exceptions=False, project_root=None, privacy_mode=False, before_send=None, flag_fallback_cache_url=None, enable_local_evaluation=True, flag_definition_cache_provider: Optional[FlagDefinitionCacheProvider] = None, capture_exception_code_variables=False, code_variables_mask_patterns=None, code_variables_ignore_patterns=None, code_variables_mask_url_credentials=None, code_variables_detect_secrets=None, in_app_modules: list[str] | None = None, enable_exception_autocapture_rate_limiting=False, exception_autocapture_bucket_size=ExceptionCapture.DEFAULT_BUCKET_SIZE, exception_autocapture_refill_rate=ExceptionCapture.DEFAULT_REFILL_RATE, exception_autocapture_refill_interval_seconds=ExceptionCapture.DEFAULT_REFILL_INTERVAL_SECONDS, capture_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_max_queue_size: int = 1000, capture_ai_timeout: float = 30, capture_ai_max_event_bytes: int = AI_MAX_MSG_SIZE, secret_key=None, metrics: Optional[dict] = None, enable_full_ai_capture=False, capture_trace_context=False, _use_ai_lane=False, _enable_multimodal_capture=False, traces: Optional[dict] = None) -class posthog.consumer.Consumer(queue, api_key, flush_at=100, host=None, on_error=None, flush_interval=5.0, retries=3, timeout=15, historical_migration=False, endpoint=_CAPTURE_V1_PATH, max_msg_size=MAX_MSG_SIZE, capture_compression=CaptureCompression.NONE) +class posthog.client.Client(project_api_key: str, host=None, *, debug=False, max_queue_size=10000, send=True, on_error=None, flush_at=100, flush_interval=5.0, max_retries=3, sync_mode=False, timeout: float = 15, thread=1, poll_interval=30, personal_api_key=None, disabled=False, disable_geoip=True, is_server=True, historical_migration=False, feature_flags_request_timeout_seconds: float = 3, feature_flags_request_max_retries=1, super_properties=None, super_options=None, enable_exception_autocapture=False, log_captured_exceptions=False, project_root=None, privacy_mode=False, before_send=None, flag_fallback_cache_url=None, enable_local_evaluation=True, flag_definition_cache_provider: Optional[FlagDefinitionCacheProvider] = None, capture_exception_code_variables=False, code_variables_mask_patterns=None, code_variables_ignore_patterns=None, code_variables_mask_url_credentials=None, code_variables_detect_secrets=None, in_app_modules: list[str] | None = None, enable_exception_autocapture_rate_limiting=False, exception_autocapture_bucket_size=ExceptionCapture.DEFAULT_BUCKET_SIZE, exception_autocapture_refill_rate=ExceptionCapture.DEFAULT_REFILL_RATE, exception_autocapture_refill_interval_seconds=ExceptionCapture.DEFAULT_REFILL_INTERVAL_SECONDS, capture_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_compression: Optional[Union[CaptureCompression, str]] = None, capture_ai_max_queue_size: int = 1000, capture_ai_timeout: float = 30, capture_ai_max_event_bytes: int = AI_MAX_MSG_SIZE, secret_key=None, metrics: Optional[dict] = None, enable_full_ai_capture=False, capture_trace_context=False, _use_ai_lane=False, _enable_multimodal_capture=False, traces: Optional[dict] = None) +class posthog.consumer.Consumer(queue, api_key, flush_at=100, host=None, on_error=None, flush_interval=5.0, retries=3, timeout: float = 15, historical_migration=False, endpoint=_CAPTURE_V1_PATH, max_msg_size=MAX_MSG_SIZE, capture_compression=CaptureCompression.NONE) class posthog.contexts.ContextScope(parent=None, fresh: bool = False, capture_exceptions: bool = True, client: Optional[Client] = None) class posthog.exception_capture.ExceptionCapture(client: Client, rate_limiting_enabled=False, bucket_size=DEFAULT_BUCKET_SIZE, refill_rate=DEFAULT_REFILL_RATE, refill_interval_seconds=DEFAULT_REFILL_INTERVAL_SECONDS) class posthog.exception_utils.AnnotatedValue(value, metadata) @@ -1515,11 +1515,11 @@ function posthog.new_context(fresh: bool = False, capture_exceptions: Optional[b function posthog.request.determine_server_host(host: Optional[str]) -> str function posthog.request.disable_connection_reuse() -> None function posthog.request.enable_keep_alive() -> None -function posthog.request.flags(api_key: str, host: Optional[str] = None, *, timeout: int = 15, max_retries: int = 1, **kwargs) -> Any -function posthog.request.get(api_key: str, url: str, host: Optional[str] = None, timeout: Optional[int] = None, etag: Optional[str] = None) -> GetResponse +function posthog.request.flags(api_key: str, host: Optional[str] = None, *, timeout: float = 15, max_retries: int = 1, **kwargs) -> Any +function posthog.request.get(api_key: str, url: str, host: Optional[str] = None, timeout: Optional[float] = None, etag: Optional[str] = None) -> GetResponse function posthog.request.normalize_host(host: Optional[str]) -> str -function posthog.request.post(api_key: str, host: Optional[str] = None, path: Optional[str] = None, *, timeout: int = 15, session: Optional[requests.Session] = None, **kwargs) -> requests.Response -function posthog.request.remote_config(personal_api_key: str, project_api_key: str, host: Optional[str] = None, key: str = '', timeout: int = 15) -> Any +function posthog.request.post(api_key: str, host: Optional[str] = None, path: Optional[str] = None, *, timeout: float = 15, session: Optional[requests.Session] = None, **kwargs) -> requests.Response +function posthog.request.remote_config(personal_api_key: str, project_api_key: str, host: Optional[str] = None, key: str = '', timeout: float = 15) -> Any function posthog.request.reset_sessions() -> None function posthog.request.set_socket_options(socket_options: Optional[SocketOptions]) -> None function posthog.scoped(fresh=False, capture_exceptions: Optional[bool] = None) diff --git a/typings/requests/__init__.pyi b/typings/requests/__init__.pyi index 1143d97b6..661c73192 100644 --- a/typings/requests/__init__.pyi +++ b/typings/requests/__init__.pyi @@ -43,5 +43,5 @@ class Session: url: str, *, headers: dict[str, str], - timeout: int | None = ..., + timeout: float | None = ..., ) -> Response: ... From d5a4cc67e935d515b2cb644a531b900f645f3d55 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:06:42 +0000 Subject: [PATCH 64/70] chore: Release v7.75.5 [skip ci] (cherry picked from commit a7742232151193989e722907d9c025045bda2631) --- .sampo/changesets/float-timeout-annotations.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/float-timeout-annotations.md diff --git a/.sampo/changesets/float-timeout-annotations.md b/.sampo/changesets/float-timeout-annotations.md deleted file mode 100644 index fd4222710..000000000 --- a/.sampo/changesets/float-timeout-annotations.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Annotate `timeout` and `feature_flags_request_timeout_seconds` as `float` on `Client`, `AsyncClient`, `Consumer` and the request helpers, so type checkers accept fractional timeouts such as `timeout=2.5`. The values were already passed straight to `requests` and `httpx`, which take floats, so runtime behaviour is unchanged. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 72530f8c3..0d7e4f0b2 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.119 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.5 + ## 0.1.118 — 2026-10-22 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index d2a95571e..9c9198041 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.118" +version = "0.1.119" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index db223afe4..7953462ba 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.75.5 — 2026-10-22 + +### Patch changes + +- [b3fcec6](https://github.com/posthog/posthog-python/commit/b3fcec639aa9c49514344ba97b24492f03e87b86) Annotate `timeout` and `feature_flags_request_timeout_seconds` as `float` on `Client`, `AsyncClient`, `Consumer` and the request helpers, so type checkers accept fractional timeouts such as `timeout=2.5`. The values were already passed straight to `requests` and `httpx`, which take floats, so runtime behaviour is unchanged. — Thanks @turnipdabeets! + ## 7.75.4 — 2026-10-22 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index 0c240c3d9..63ec533cb 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.4" +VERSION = "7.75.5" diff --git a/pyproject.toml b/pyproject.toml index 76c7cf5ec..7ea7bd739 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.4" +version = "7.75.5" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index 883350e13..c0486930b 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.118" +version = "0.1.119" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.4" +version = "7.75.5" source = { editable = "." } dependencies = [ { name = "distro" }, From 95ca84a4d3f7238a8e16e83b67bc27b6ba9dc775 Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:06:47 +0000 Subject: [PATCH 65/70] Update generated references (cherry picked from commit 8c2d8f625f7c40cfc3b87f47dc65bc15c4721d7b) --- .../posthog-python-references-7.75.5.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 6 +- 2 files changed, 3551 insertions(+), 3 deletions(-) create mode 100644 references/posthog-python-references-7.75.5.json diff --git a/references/posthog-python-references-7.75.5.json b/references/posthog-python-references-7.75.5.json new file mode 100644 index 000000000..342f66487 --- /dev/null +++ b/references/posthog-python-references-7.75.5.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.5", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "float" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "float" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 2cd75278e..342f66487 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.4", + "version": "7.75.5", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", @@ -437,7 +437,7 @@ "name": "timeout", "description": "HTTP request timeout in seconds for event uploads.", "isOptional": false, - "type": "int" + "type": "float" }, { "name": "thread", @@ -485,7 +485,7 @@ "name": "feature_flags_request_timeout_seconds", "description": "Timeout in seconds for feature flag and remote config requests.", "isOptional": false, - "type": "int" + "type": "float" }, { "name": "feature_flags_request_max_retries", From 845b9615f27ce982c1a518b1e092479e3aac7aeb Mon Sep 17 00:00:00 2001 From: Dustin Byrne Date: Thu, 22 Oct 2026 14:08:37 -0400 Subject: [PATCH 66/70] fix(flags): retain tracking metadata in local evaluation snapshots (#1041) (cherry picked from commit a95331f171a33ca0674833a5aada371cc6446bc9) --- .../local-snapshot-tracking-metadata.md | 5 ++ posthog/client.py | 46 +++++----- .../test_feature_flag_called_minimization.py | 86 +++++++++++++++++++ .../test/test_property_matching_version.py | 2 +- 4 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 .sampo/changesets/local-snapshot-tracking-metadata.md diff --git a/.sampo/changesets/local-snapshot-tracking-metadata.md b/.sampo/changesets/local-snapshot-tracking-metadata.md new file mode 100644 index 000000000..82b003845 --- /dev/null +++ b/.sampo/changesets/local-snapshot-tracking-metadata.md @@ -0,0 +1,5 @@ +--- +pypi/posthog: patch +--- + +Retain the minimal-event gate and experiment metadata from the local definitions used by `evaluate_flags()`, including first-use loading and definition refreshes during evaluation. diff --git a/posthog/client.py b/posthog/client.py index 19744b9e5..b39a4cb4c 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -3465,6 +3465,7 @@ def _local_evaluation_snapshot(self) -> _LocalEvaluationSnapshot: "group_type_mapping": self.group_type_mapping or {}, "cohorts": self.cohorts or {}, "property_matching_version": self._property_matching_version, + "minimal_flag_called_events": self._minimal_flag_called_events, "flag_definition_version": self.flag_definition_version, } @@ -4657,7 +4658,7 @@ def get_all_flags_and_payloads( local_person_properties = self._person_properties_for_local_evaluation( distinct_id, person_properties ) - response, fallback_to_flags = self._get_all_flags_and_payloads_locally( + response, fallback_to_flags, _ = self._get_all_flags_and_payloads_locally( distinct_id, groups=groups, person_properties=local_person_properties, @@ -4794,26 +4795,27 @@ def evaluate_flags( errors_while_computing = False quota_limited = False locally_evaluated_keys: set[str] = set() - # Source the gate the same way as has_experiment below; see - # _capture_feature_flag_called_if_needed for why. Defaults to the poller's - # current state; a successful remote fallback overwrites it with that - # response's own field below. - minimal_flag_called_events = self._minimal_flag_called_events - # Try local evaluation first when the poller has loaded definitions. local_person_properties = self._person_properties_for_local_evaluation( distinct_id, person_properties ) - local_result, fallback_to_server = self._get_all_flags_and_payloads_locally( - distinct_id, - groups=dict(groups), - person_properties=local_person_properties, - group_properties=group_properties, - flag_keys_to_evaluate=flag_keys, - device_id=device_id, + local_result, fallback_to_server, definition_snapshot = ( + self._get_all_flags_and_payloads_locally( + distinct_id, + groups=dict(groups), + person_properties=local_person_properties, + group_properties=group_properties, + flag_keys_to_evaluate=flag_keys, + device_id=device_id, + ) ) - feature_flags_by_key: Dict[str, Any] = self.feature_flags_by_key or {} + # Pin local tracking metadata to the definitions used for these values. + # A successful remote fallback below supplies its own gate instead. + minimal_flag_called_events = definition_snapshot.get( + "minimal_flag_called_events", False + ) + feature_flags_by_key = definition_snapshot["flags_by_key"] local_flags = local_result.get("featureFlags") or {} local_payloads = local_result.get("featureFlagPayloads") or {} if requested_keys and not requested_keys.issubset(local_flags): @@ -4937,7 +4939,7 @@ def _get_all_flags_and_payloads_locally( warn_on_unknown_groups=False, flag_keys_to_evaluate: Optional[list[str]] = None, device_id: Optional[str] = None, - ) -> tuple[FlagsAndPayloads, bool]: + ) -> tuple[FlagsAndPayloads, bool, _LocalEvaluationSnapshot]: person_properties = person_properties or {} group_properties = group_properties or {} @@ -4988,10 +4990,14 @@ def _get_all_flags_and_payloads_locally( else: fallback_to_flags = True - return { - "featureFlags": flags, - "featureFlagPayloads": payloads, - }, fallback_to_flags + return ( + { + "featureFlags": flags, + "featureFlagPayloads": payloads, + }, + fallback_to_flags, + snapshot, + ) def _initialize_flag_cache(self, cache_url): """Initialize feature flag cache for graceful degradation during service outages. diff --git a/posthog/test/test_feature_flag_called_minimization.py b/posthog/test/test_feature_flag_called_minimization.py index 81cf76a1f..837517582 100644 --- a/posthog/test/test_feature_flag_called_minimization.py +++ b/posthog/test/test_feature_flag_called_minimization.py @@ -415,6 +415,92 @@ def _snapshot_response(self, has_experiment, gate): response["minimalFlagCalledEvents"] = gate return response + @parameterized.expand([("api",), ("cache",)]) + @mock.patch("posthog.client.flags") + @mock.patch("posthog.client.get") + def test_lazy_local_snapshot_retains_loaded_minimal_gate( + self, source, patch_get, patch_flags + ): + definitions = { + "flags": [_local_flag_definition(False)], + "group_type_mapping": {}, + "cohorts": {}, + "minimal_flag_called_events": True, + } + patch_get.return_value = GetResponse(data=definitions, etag='"etag-1"') + provider = None + if source == "cache": + provider = mock.Mock() + provider.should_fetch_flag_definitions.return_value = False + provider.get_flag_definitions.return_value = definitions + provider.shutdown.return_value = None + client, captured = self._make_client( + secret_key="personal-key", + enable_local_evaluation=False, + flag_definition_cache_provider=provider, + ) + self.addCleanup(client.shutdown) + + snapshot = client.evaluate_flags("user-1") + self.assertTrue(snapshot.get_flag("person-flag")) + + properties = self._flag_called_properties(captured) + self.assertLessEqual(set(properties), _MINIMAL_FLAG_CALLED_EVENT_PROPERTIES) + self.assertNotIn("app_version", properties) + self.assertIs(properties["locally_evaluated"], True) + patch_flags.assert_not_called() + if source == "cache": + patch_get.assert_not_called() + else: + patch_get.assert_called_once() + + @parameterized.expand([("gate_on", True), ("gate_off", False)]) + @mock.patch("posthog.client.flags") + @mock.patch("posthog.client.get") + def test_local_snapshot_retains_metadata_when_definitions_refresh_during_evaluation( + self, _name, gate, patch_get, patch_flags + ): + definitions = { + "flags": [_local_flag_definition(False)], + "group_type_mapping": {}, + "cohorts": {}, + "minimal_flag_called_events": gate, + } + patch_get.return_value = GetResponse(data=definitions, etag='"etag-1"') + client, captured = self._make_client( + secret_key="personal-key", enable_local_evaluation=False + ) + self.addCleanup(client.shutdown) + original_compute = client._compute_flag_locally + + def evaluate_then_refresh(*args, **kwargs): + value = original_compute(*args, **kwargs) + # A poll publishes new tracking metadata while this evaluation is + # still using the previous definition snapshot. + client._update_flag_state( + { + **definitions, + "flags": [_local_flag_definition(True)], + "minimal_flag_called_events": not gate, + } + ) + return value + + with mock.patch.object( + client, "_compute_flag_locally", side_effect=evaluate_then_refresh + ): + snapshot = client.evaluate_flags("user-1") + self.assertTrue(snapshot.get_flag("person-flag")) + + properties = self._flag_called_properties(captured) + self.assertIs(properties["$feature_flag_has_experiment"], False) + if gate: + self.assertLessEqual(set(properties), _MINIMAL_FLAG_CALLED_EVENT_PROPERTIES) + self.assertNotIn("app_version", properties) + else: + self.assertEqual(properties["app_version"], "1.2.3") + patch_flags.assert_not_called() + @mock.patch("posthog.client.flags") def test_gated_non_experiment_flag_sends_exactly_the_allowlist(self, patch_flags): patch_flags.return_value = self._snapshot_response( diff --git a/posthog/test/test_property_matching_version.py b/posthog/test/test_property_matching_version.py index 640efacb5..f6f1f8774 100644 --- a/posthog/test/test_property_matching_version.py +++ b/posthog/test/test_property_matching_version.py @@ -238,7 +238,7 @@ def reload_during_evaluation(*args, **kwargs): "posthog.client.match_feature_flag_properties", side_effect=reload_during_evaluation, ): - result, fallback = client._get_all_flags_and_payloads_locally( + result, fallback, _ = client._get_all_flags_and_payloads_locally( "user", groups={"company": "company-id"}, person_properties={"value": "banana"}, From f96542b18df55131559fb19a3f196303d83e4c7d Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:11:33 +0000 Subject: [PATCH 67/70] chore: Release v7.75.6 [skip ci] (cherry picked from commit a5909dc4d507e36a7cb08b21a685ca8b06d7f7de) --- .sampo/changesets/local-snapshot-tracking-metadata.md | 5 ----- openfeature-provider/CHANGELOG.md | 6 ++++++ openfeature-provider/pyproject.toml | 2 +- posthog/CHANGELOG.md | 6 ++++++ posthog/version.py | 2 +- pyproject.toml | 2 +- uv.lock | 4 ++-- 7 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 .sampo/changesets/local-snapshot-tracking-metadata.md diff --git a/.sampo/changesets/local-snapshot-tracking-metadata.md b/.sampo/changesets/local-snapshot-tracking-metadata.md deleted file mode 100644 index 82b003845..000000000 --- a/.sampo/changesets/local-snapshot-tracking-metadata.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -pypi/posthog: patch ---- - -Retain the minimal-event gate and experiment metadata from the local definitions used by `evaluate_flags()`, including first-use loading and definition refreshes during evaluation. diff --git a/openfeature-provider/CHANGELOG.md b/openfeature-provider/CHANGELOG.md index 0d7e4f0b2..2d706fe7c 100644 --- a/openfeature-provider/CHANGELOG.md +++ b/openfeature-provider/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to `openfeature-provider-posthog` are documented here. This file is maintained by [Sampo](https://github.com/bruits/sampo) from changesets in `.sampo/changesets/` that target `pypi/openfeature-provider-posthog`. +## 0.1.120 — 2026-10-22 + +### Patch changes + +- Updated dependencies: posthog@7.75.6 + ## 0.1.119 — 2026-10-22 ### Patch changes diff --git a/openfeature-provider/pyproject.toml b/openfeature-provider/pyproject.toml index 9c9198041..c0bec33a1 100644 --- a/openfeature-provider/pyproject.toml +++ b/openfeature-provider/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "openfeature-provider-posthog" -version = "0.1.119" +version = "0.1.120" description = "Official PostHog provider for the OpenFeature Python SDK." readme = "README.md" authors = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/posthog/CHANGELOG.md b/posthog/CHANGELOG.md index 7953462ba..0219635ea 100644 --- a/posthog/CHANGELOG.md +++ b/posthog/CHANGELOG.md @@ -1,5 +1,11 @@ # posthog +## 7.75.6 — 2026-10-22 + +### Patch changes + +- [a95331f](https://github.com/posthog/posthog-python/commit/a95331f171a33ca0674833a5aada371cc6446bc9) Retain the minimal-event gate and experiment metadata from the local definitions used by `evaluate_flags()`, including first-use loading and definition refreshes during evaluation. — Thanks @dustinbyrne! + ## 7.75.5 — 2026-10-22 ### Patch changes diff --git a/posthog/version.py b/posthog/version.py index 63ec533cb..4121f4176 100644 --- a/posthog/version.py +++ b/posthog/version.py @@ -1 +1 @@ -VERSION = "7.75.5" +VERSION = "7.75.6" diff --git a/pyproject.toml b/pyproject.toml index 7ea7bd739..fdb74b179 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "posthog" -version = "7.75.5" +version = "7.75.6" description = "Integrate PostHog into any python application." authors = [{ name = "PostHog", email = "engineering@posthog.com" }] maintainers = [{ name = "PostHog", email = "engineering@posthog.com" }] diff --git a/uv.lock b/uv.lock index c0486930b..7b8aa80bd 100644 --- a/uv.lock +++ b/uv.lock @@ -2653,7 +2653,7 @@ wheels = [ [[package]] name = "openfeature-provider-posthog" -version = "0.1.119" +version = "0.1.120" source = { editable = "openfeature-provider" } dependencies = [ { name = "openfeature-sdk" }, @@ -3012,7 +3012,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.75.5" +version = "7.75.6" source = { editable = "." } dependencies = [ { name = "distro" }, From 91ebcc7ab4a48f70ddc051f79e10379a4d2a3a8a Mon Sep 17 00:00:00 2001 From: "releaser-posthog-python[bot]" <262414804+releaser-posthog-python[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 18:11:39 +0000 Subject: [PATCH 68/70] Update generated references (cherry picked from commit 4b280fcace78f10af24ef47bac1fa7ff7d9b56c9) --- .../posthog-python-references-7.75.6.json | 3548 +++++++++++++++++ .../posthog-python-references-latest.json | 2 +- 2 files changed, 3549 insertions(+), 1 deletion(-) create mode 100644 references/posthog-python-references-7.75.6.json diff --git a/references/posthog-python-references-7.75.6.json b/references/posthog-python-references-7.75.6.json new file mode 100644 index 000000000..ecbda11e3 --- /dev/null +++ b/references/posthog-python-references-7.75.6.json @@ -0,0 +1,3548 @@ +{ + "id": "posthog-python", + "hogRef": "0.3", + "info": { + "version": "7.75.6", + "id": "posthog-python", + "title": "PostHog Python SDK", + "description": "Integrate PostHog into any python application.", + "slugPrefix": "posthog-python", + "specUrl": "https://github.com/PostHog/posthog-python" + }, + "types": [ + { + "id": "FeatureFlag", + "name": "FeatureFlag", + "path": "posthog.types.FeatureFlag", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "reason", + "type": "Optional[FlagReason]", + "description": "Field: reason" + }, + { + "name": "metadata", + "type": "Union[FlagMetadata, LegacyFlagMetadata]", + "description": "Field: metadata" + } + ], + "example": "" + }, + { + "id": "FeatureFlagResult", + "name": "FeatureFlagResult", + "path": "posthog.types.FeatureFlagResult", + "properties": [ + { + "name": "key", + "type": "str", + "description": "Field: key" + }, + { + "name": "enabled", + "type": "bool", + "description": "Field: enabled" + }, + { + "name": "variant", + "type": "Optional[str]", + "description": "Field: variant" + }, + { + "name": "payload", + "type": "Optional[Any]", + "description": "Field: payload" + }, + { + "name": "reason", + "type": "Optional[str]", + "description": "Field: reason" + } + ], + "example": "" + }, + { + "id": "FlagMetadata", + "name": "FlagMetadata", + "path": "posthog.types.FlagMetadata", + "properties": [ + { + "name": "id", + "type": "int", + "description": "Field: id" + }, + { + "name": "payload", + "type": "Optional[str]", + "description": "Field: payload" + }, + { + "name": "version", + "type": "int", + "description": "Field: version" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + }, + { + "name": "has_experiment", + "type": "Optional[bool]", + "description": "Field: has_experiment" + } + ], + "example": "" + }, + { + "id": "FlagReason", + "name": "FlagReason", + "path": "posthog.types.FlagReason", + "properties": [ + { + "name": "code", + "type": "str", + "description": "Field: code" + }, + { + "name": "condition_index", + "type": "Optional[int]", + "description": "Field: condition_index" + }, + { + "name": "description", + "type": "str", + "description": "Field: description" + } + ], + "example": "" + }, + { + "id": "FlagsAndPayloads", + "name": "FlagsAndPayloads", + "path": "posthog.types.FlagsAndPayloads", + "properties": [ + { + "name": "featureFlags", + "type": "Optional[dict[str, Union[bool, str]]]", + "description": "Field: featureFlags" + }, + { + "name": "featureFlagPayloads", + "type": "Optional[dict[str, Any]]", + "description": "Field: featureFlagPayloads" + } + ], + "example": "" + }, + { + "id": "FlagsResponse", + "name": "FlagsResponse", + "path": "posthog.types.FlagsResponse", + "properties": [ + { + "name": "flags", + "type": "dict[str, FeatureFlag]", + "description": "Field: flags" + }, + { + "name": "errorsWhileComputingFlags", + "type": "bool", + "description": "Field: errorsWhileComputingFlags" + }, + { + "name": "requestId", + "type": "str", + "description": "Field: requestId" + }, + { + "name": "quotaLimit", + "type": "Optional[list[str]]", + "description": "Field: quotaLimit" + }, + { + "name": "evaluatedAt", + "type": "Optional[int]", + "description": "Field: evaluatedAt" + }, + { + "name": "minimalFlagCalledEvents", + "type": "bool", + "description": "Field: minimalFlagCalledEvents" + } + ], + "example": "" + }, + { + "id": "LegacyFlagMetadata", + "name": "LegacyFlagMetadata", + "path": "posthog.types.LegacyFlagMetadata", + "properties": [ + { + "name": "payload", + "type": "Any", + "description": "Field: payload" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + }, + { + "id": "OptionalCaptureArgs", + "name": "OptionalCaptureArgs", + "path": "posthog.args.OptionalCaptureArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "groups", + "type": "NotRequired[Optional[dict[str, str]]]", + "description": "Field: groups" + }, + { + "name": "flags", + "type": "NotRequired[Optional[ForwardRef('FeatureFlagEvaluations')]]", + "description": "Field: flags" + }, + { + "name": "send_feature_flags", + "type": "NotRequired[Union[bool, SendFeatureFlagsOptions, any]]", + "description": "Field: send_feature_flags" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + }, + { + "name": "_property_allowlist", + "type": "NotRequired[Optional[frozenset[str]]]", + "description": "Field: _property_allowlist" + } + ], + "example": "" + }, + { + "id": "OptionalSetArgs", + "name": "OptionalSetArgs", + "path": "posthog.args.OptionalSetArgs", + "properties": [ + { + "name": "distinct_id", + "type": "NotRequired[Union[Number, str, UUID, int, any]]", + "description": "Field: distinct_id" + }, + { + "name": "properties", + "type": "NotRequired[Optional[dict[str, Any]]]", + "description": "Field: properties" + }, + { + "name": "timestamp", + "type": "NotRequired[Union[datetime, str, any]]", + "description": "Field: timestamp" + }, + { + "name": "uuid", + "type": "NotRequired[Union[str, UUID, any]]", + "description": "Field: uuid" + }, + { + "name": "disable_geoip", + "type": "NotRequired[Optional[bool]]", + "description": "Field: disable_geoip" + } + ], + "example": "" + }, + { + "id": "SendFeatureFlagsOptions", + "name": "SendFeatureFlagsOptions", + "path": "posthog.types.SendFeatureFlagsOptions", + "properties": [ + { + "name": "should_send", + "type": "bool", + "description": "Field: should_send" + }, + { + "name": "only_evaluate_locally", + "type": "Optional[bool]", + "description": "Field: only_evaluate_locally" + }, + { + "name": "person_properties", + "type": "Optional[dict[str, Any]]", + "description": "Field: person_properties" + }, + { + "name": "group_properties", + "type": "Optional[dict[str, dict[str, Any]]]", + "description": "Field: group_properties" + }, + { + "name": "flag_keys_filter", + "type": "Optional[list[str]]", + "description": "Field: flag_keys_filter" + } + ], + "example": "" + } + ], + "classes": [ + { + "id": "PostHog", + "title": "PostHog", + "description": "This is the SDK reference for the PostHog Python SDK. You can learn more about example usage in the [Python SDK documentation](/docs/libraries/python). You can also follow [Flask](/docs/libraries/flask) and [Django](/docs/libraries/django) guides to integrate PostHog into your project. For long-running applications, create one client during application startup and reuse it for the lifetime of the process. This keeps background queues predictable and makes shutdown flushing straightforward. Multiple clients are still supported for intentional multi-project or multi-host setups.", + "functions": [ + { + "id": "__init__", + "title": "Client", + "description": "Initialize a new PostHog client instance.", + "details": "", + "category": "Initialization", + "params": [ + { + "name": "project_api_key", + "description": "PostHog project API key/token.", + "isOptional": true, + "type": "str" + }, + { + "name": "host", + "description": "PostHog host. Defaults to the US ingestion endpoint when not set. App hosts such as ``https://us.posthog.com`` are mapped to the corresponding ingestion host.", + "isOptional": false, + "type": "any" + }, + { + "name": "debug", + "description": "Enable verbose SDK logging and re-raise errors from public API methods.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_queue_size", + "description": "Maximum number of events buffered before upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "send", + "description": "If False, queueing succeeds but events are not sent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "on_error", + "description": "Optional callback invoked by background consumers when an upload fails. Keep it short and non-blocking. Calling lifecycle methods directly is safe and deferred, but do not start another thread or task that calls ``flush()``, ``join()``, or ``shutdown()`` and then wait for it from the callback.", + "isOptional": false, + "type": "any" + }, + { + "name": "flush_at", + "description": "Number of queued events that triggers a batch upload.", + "isOptional": false, + "type": "int" + }, + { + "name": "flush_interval", + "description": "Maximum seconds a background consumer waits before flushing a partial batch.", + "isOptional": false, + "type": "float" + }, + { + "name": "gzip", + "description": "Whether to gzip event upload payloads.", + "isOptional": false, + "type": "bool" + }, + { + "name": "max_retries", + "description": "Number of upload retries. Values below 0 are treated as 0.", + "isOptional": false, + "type": "int" + }, + { + "name": "sync_mode", + "description": "If True, send each event synchronously instead of using background worker threads. This blocks the calling thread; in asyncio applications such as FastAPI, use ``AsyncPosthog`` instead.", + "isOptional": false, + "type": "bool" + }, + { + "name": "timeout", + "description": "HTTP request timeout in seconds for event uploads.", + "isOptional": false, + "type": "float" + }, + { + "name": "thread", + "description": "Number of background consumer threads.", + "isOptional": false, + "type": "int" + }, + { + "name": "poll_interval", + "description": "Seconds between local feature flag definition refreshes.", + "isOptional": false, + "type": "int" + }, + { + "name": "personal_api_key", + "description": "Deprecated alias for ``secret_key``. Still honored for backwards compatibility; prefer ``secret_key``, which also accepts a Project Secret API Key.", + "isOptional": false, + "type": "any" + }, + { + "name": "disabled", + "description": "If True, disable captures and API requests. Useful in tests.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable server-side GeoIP enrichment. Defaults to True.", + "isOptional": false, + "type": "bool" + }, + { + "name": "is_server", + "description": "Whether events are emitted from a server-side runtime. Defaults to True; set to False when using the SDK as a client/CLI so the device OS is attributed to the person normally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "historical_migration", + "description": "Mark events as historical migration imports.", + "isOptional": false, + "type": "bool" + }, + { + "name": "feature_flags_request_timeout_seconds", + "description": "Timeout in seconds for feature flag and remote config requests.", + "isOptional": false, + "type": "float" + }, + { + "name": "feature_flags_request_max_retries", + "description": "Number of retries for feature flag requests after network, transport, or timeout failures. Defaults to 1. Set to 0 to disable retries.", + "isOptional": false, + "type": "int" + }, + { + "name": "super_properties", + "description": "Properties merged into every captured event.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_exception_autocapture", + "description": "Automatically capture uncaught exceptions.", + "isOptional": false, + "type": "bool" + }, + { + "name": "log_captured_exceptions", + "description": "Also log exceptions captured by error tracking.", + "isOptional": false, + "type": "bool" + }, + { + "name": "project_root", + "description": "Root path used to determine in-app stack frames for captured exceptions. Defaults to the current working directory.", + "isOptional": false, + "type": "any" + }, + { + "name": "privacy_mode", + "description": "For AI observability, capture usage metadata without prompt inputs or outputs.", + "isOptional": false, + "type": "bool" + }, + { + "name": "before_send", + "description": "Optional callback that can modify or drop events before upload. Return ``None`` to drop an event.", + "isOptional": false, + "type": "any" + }, + { + "name": "flag_fallback_cache_url", + "description": "Optional feature flag fallback cache URL, such as ``memory://local/?ttl=300&size=10000`` or a Redis URL.", + "isOptional": false, + "type": "any" + }, + { + "name": "enable_local_evaluation", + "description": "Whether to poll feature flag definitions for local evaluation when a personal API key is configured.", + "isOptional": false, + "type": "bool" + }, + { + "name": "flag_definition_cache_provider", + "description": "Optional external cache provider for sharing feature flag definitions across workers.", + "isOptional": true, + "type": "FlagDefinitionCacheProvider" + }, + { + "name": "capture_exception_code_variables", + "description": "Capture local variable values on exception stack frames.", + "isOptional": false, + "type": "bool" + }, + { + "name": "code_variables_mask_patterns", + "description": "Variable-name patterns to mask when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_ignore_patterns", + "description": "Variable-name patterns to omit when capturing code variables.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_mask_url_credentials", + "description": "Scrub credentials embedded in URLs/DSNs (e.g. ``user:pass@host``) from captured code variables, regardless of the surrounding variable name. Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "code_variables_detect_secrets", + "description": "Last-resort entropy-based detection that redacts high-entropy secret-looking values (API keys, tokens, strong passwords) sitting in innocuously-named variables, after the name and URL checks. Skips structured ids (UUIDs, ObjectIds, hashes). Defaults to True.", + "isOptional": false, + "type": "any" + }, + { + "name": "in_app_modules", + "description": "Module/package prefixes treated as in-app frames in captured exceptions.", + "isOptional": false, + "type": "UnionType[list[str], any]" + }, + { + "name": "enable_exception_autocapture_rate_limiting", + "description": "Rate limit autocaptured exceptions client-side with a token bucket per exception type. Disabled by default.", + "isOptional": false, + "type": "bool" + }, + { + "name": "exception_autocapture_bucket_size", + "description": "Maximum burst of autocaptured exceptions allowed per exception type (token bucket size, clamped to 0-100).", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_rate", + "description": "Tokens restored per refill interval for each exception type's bucket.", + "isOptional": false, + "type": "int" + }, + { + "name": "exception_autocapture_refill_interval_seconds", + "description": "Seconds between token refills for autocaptured exception rate limiting.", + "isOptional": false, + "type": "int" + }, + { + "name": "capture_mode", + "description": "Capture wire protocol to use. Defaults to ``CaptureMode.V0`` (legacy ``/batch/``). Set ``CaptureMode.V1`` (or pass the string ``\"v1\"``) to opt into ``/i/v1/analytics/events``. When omitted, the ``POSTHOG_CAPTURE_MODE`` env var is consulted, then ``V0``.", + "isOptional": false, + "type": "CaptureMode" + }, + { + "name": "capture_compression", + "description": "Request-body compression for capture-v1 uploads (ignored in V0, which uses ``gzip``). ``CaptureCompression.GZIP`` or ``DEFLATE`` (or the strings ``\"gzip\"``/``\"deflate\"``). When omitted, the ``POSTHOG_CAPTURE_COMPRESSION`` env var is consulted, then the legacy ``gzip`` flag, then no compression.", + "isOptional": false, + "type": "CaptureCompression" + }, + { + "name": "secret_key", + "description": "A Personal API Key or Project Secret API Key, used to authenticate local feature flag evaluation, remote config payloads, and decrypted flag payloads. Example:: posthog.Client(project_api_key, secret_key=\"phx_...\")", + "isOptional": false, + "type": "any" + }, + { + "name": "metrics", + "description": "", + "isOptional": true, + "type": "dict" + }, + { + "name": "enable_full_ai_capture", + "description": "Route PostHog AI wrapper events through the dedicated AI capture endpoint and capture full AI content: skips string truncation and passes media (base64/data URIs) through unredacted. ``privacy_mode`` always wins. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_trace_context", + "description": "When OpenTelemetry is installed and a valid span is active at capture time, add its trace and span IDs as ``$trace_id`` and ``$span_id`` properties to events captured with ``capture()`` and ``capture_ai()``, so they can be correlated with backend traces. Explicit ``$trace_id``/``$span_id`` values passed in ``properties`` win. Exception events (``capture_exception``) always attach these IDs regardless of this setting. Defaults to False.", + "isOptional": false, + "type": "bool" + }, + { + "name": "_use_ai_lane", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "_enable_multimodal_capture", + "description": "", + "isOptional": false, + "type": "bool" + }, + { + "name": "traces", + "description": "Config dict for distributed tracing: ``service_name``, ``service_version``, ``environment``, ``resource_attributes``, ``flush_interval`` (5 s), ``max_queue_size`` (2048), ``max_export_batch_size`` (512), ``max_live_spans`` (10000), ``max_span_age`` (3600 s), ``max_attributes_per_span`` (128), ``max_events_per_span`` (128), ``max_attribute_value_length`` (8192). ``before_span_send`` is a callable, or a list run in order, that receives each finished span as a dict (``trace_id``, ``span_id`` and ``parent_span_id`` are read-only) and returns it, edited, or ``None`` to drop it; a hook that raises drops the span. Tracing is off until this is provided. Spans export on a background timer even with ``sync_mode``; serverless handlers should call ``flush()`` before returning. Defaults to None.", + "isOptional": true, + "type": "dict" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import Posthog\n\nposthog = Posthog('', host='')" + } + ] + }, + { + "id": "alias", + "title": "alias", + "description": "Create an alias between two distinct IDs.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The previous distinct ID. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The new distinct ID to alias to. Falls back to the context distinct ID; the call is dropped with a warning if neither is available.", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.alias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Captures an event manually. [Learn about capture best practices](https://posthog.com/docs/product-analytics/capture-events)", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "The event name to capture.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Anonymous event", + "code": "# Anonymous event\nposthog.capture('some-anon-event')" + }, + { + "id": "example_2", + "name": "Context usage", + "code": "# Context usage\nfrom posthog import identify_context, new_context\nwith new_context():\n identify_context('distinct_id_of_the_user')\n posthog.capture('user_signed_up')\n posthog.capture('user_logged_in')\n posthog.capture('some-custom-action', distinct_id='distinct_id_of_the_user')" + }, + { + "id": "example_3", + "name": "Set event properties", + "code": "# Set event properties\nposthog.capture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + }, + { + "id": "example_4", + "name": "Page view event", + "code": "# Page view event\nposthog.capture('$pageview', distinct_id=\"distinct_id_of_the_user\", properties={'$current_url': 'https://example.com'})" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is queued on an isolated AI lane with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Capture", + "params": [ + { + "name": "event", + "description": "", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + } + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture an exception for error tracking. When OpenTelemetry is installed and a valid span is active, its trace and span IDs are added as ``$trace_id`` and ``$span_id`` event properties.", + "details": "", + "category": "Error Tracking", + "params": [ + { + "name": "exception", + "description": "The exception to capture.", + "isOptional": true, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "try:\n # Some code that might fail\n pass\nexcept Exception as e:\n posthog.capture_exception(e, 'user_distinct_id', properties=additional_properties)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to :meth:`capture` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request. Local evaluation is transparent: when the poller resolves a flag, the snapshot's ``$feature_flag_called`` events are tagged ``locally_evaluated=True`` and reason ``\"Evaluated locally\"``.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If True, never fall back to remote evaluation \u2014 flags that can't be evaluated locally are simply omitted from the snapshot.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is True. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flags = posthog.evaluate_flags(\n \"user_123\",\n person_properties={\"plan\": \"enterprise\"},\n)\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\nposthog.capture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Check if a feature flag is enabled for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Return feature flag definitions loaded for local evaluation. Returns: The currently loaded feature flag definitions, or ``None`` before local evaluation has loaded definitions.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the client reusable. For a client shared across requests or serverless invocations (including the module-level client), call ``flush()`` before a short-lived invocation returns. Use ``shutdown()`` instead only for final process cleanup or when disposing of a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by the consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": null, + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently. The span exporter waits up to this many seconds for an in-flight flush, then uses a fresh drain budget once it acquires the lock. If the lock wait times out, the in-flight flush is left to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. Each span request is bounded by the client's ``timeout`` in seconds, and the last request is not cut short. This is therefore not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the shared client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all feature flags for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flags and their payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.get_all_flags_and_payloads('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get multivariate feature flag value for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "enabled_variant = posthog.get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key': # replace 'variant-key' with the key of your variant\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nruntime = posthog.get_feature_flag_evaluation_runtime(\"my-flag\")\nif runtime is FeatureFlagEvaluationRuntime.SERVER:\n ..." + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate. A flag set to ``FeatureFlagEvaluationRuntime.ALL`` suits either runtime, so it is returned for ``CLIENT`` and for ``SERVER``, and asking for ``ALL`` returns every loaded flag. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "The runtime to match, as a ``FeatureFlagEvaluationRuntime`` or its string value.", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime\n\nclient_keys = posthog.get_feature_flag_keys_by_evaluation_runtime(\n FeatureFlagEvaluationRuntime.CLIENT\n)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload for a feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "The specific flag value to get payload for.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Deprecated. Use get_feature_flag() instead if you need events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "is_my_flag_enabled = posthog.feature_enabled('flag-key', 'distinct_id_of_your_user')\n\nif is_my_flag_enabled:\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = posthog.get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload for a key by evaluating locally or remotely depending on whether local evaluation is enabled and the flag can be locally evaluated. This also captures the `$feature_flag_called` event unless `send_feature_flag_events` is `False`.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to only evaluate locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "flag_result = posthog.get_feature_flag_result('flag-key', 'distinct_id_of_your_user')\nif flag_result and flag_result.get_value() == 'variant-key':\n # Do something differently for this user\n # Optional: fetch the payload\n matched_flag_payload = flag_result.payload" + } + ] + }, + { + "id": "get_feature_flags_and_payloads", + "title": "get_feature_flags_and_payloads", + "description": "Get feature flags and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "result = posthog.get_feature_flags_and_payloads('')" + } + ] + }, + { + "id": "get_feature_payloads", + "title": "get_feature_payloads", + "description": "Get feature flag payloads for a user, preserving valid serialized JSON.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Optional[str]]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "payloads = posthog.get_feature_payloads('')" + } + ] + }, + { + "id": "get_feature_variants", + "title": "get_feature_variants", + "description": "Get feature flag variants for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Union[bool, str]]" + } + }, + { + "id": "get_flags_decision", + "title": "get_flags_decision", + "description": "Get feature flags decision.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID of the user.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "A dictionary of group information.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "A dictionary of person properties.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "A dictionary of group properties.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this request.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys_to_evaluate", + "description": "A list of specific flag keys to evaluate. If provided, only these flags will be evaluated, improving performance.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "The device ID for this request.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsResponse" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "decision = posthog.get_flags_decision('user123')" + } + ] + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The remote config feature flag key.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context.", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Identify a group and set its properties.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "The type of group (e.g., 'company', 'team'). Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "The unique identifier for the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "A dictionary of properties to set on the group.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "The timestamp of the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "A unique identifier for the event. If provided, it must be a valid UUID string or uuid.UUID instance; invalid values are ignored and replaced with a newly generated UUID.", + "isOptional": false, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP for this event.", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "The distinct ID of the user performing the action.", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.group_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and end the consumer threads. Do not use directly, call `shutdown()` instead. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.join()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flags for local evaluation.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.load_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context for managing shared state. Learn more about [contexts](/docs/libraries/python#contexts).", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "with client.new_context():\n client.identify_context('')\n client.capture('event_name')" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the wrapped function using this client.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to create a fresh context that doesn't inherit from parent.", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to automatically capture exceptions in this context. If omitted, defaults to this client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a person profile.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set with distinct id", + "code": "# Set with distinct id\nposthog.set(distinct_id='user123', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a person profile only if they haven't been set before.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.set_once(distinct_id='user123', properties={'initial_signup_date': '2024-01-01'})" + } + ] + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the client. Call this for final process cleanup or when disposing of a client that will not be reused. It closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. Do not call it at the end of each request or serverless invocation when the client is shared; call ``flush()`` before returning instead. A shut-down client cannot be reused; create a new client if needed. Normally this method blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get one final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Any spans it cannot send are discarded with a warning, as are spans still open. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. When called directly from an SDK callback such as ``on_error``, shutdown is deferred to avoid blocking the worker that invoked the callback. If the callback must coordinate a blocking shutdown, have it signal an application-owned thread and return before that thread calls shutdown. Do not wait inside the callback for another thread or task that calls a lifecycle method.", + "details": "", + "category": null, + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog.shutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span. A forked child starts with no active span; pass the parent span to continue a trace across a fork.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "posthog = Posthog(\"\", traces={\"service_name\": \"checkout-api\"})\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value.", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + } + } + ] + }, + { + "id": "PostHogModule", + "title": "PostHog Module Functions", + "description": "Global functions available in the PostHog module", + "functions": [ + { + "id": "alias", + "title": "alias", + "description": "Associate user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "details": "To marry up whatever a user does before they sign up or log in with what they do after you need to make an alias call. This will allow you to answer questions like \"Which marketing channels leads to users churning after a month?\" or \"What do users do on our website before signing up?\". Particularly useful for associating user behaviour before and after they e.g. register, login, or perform some other identifying action.", + "category": "Identification", + "params": [ + { + "name": "previous_id", + "description": "The unique ID of the user before", + "isOptional": true, + "type": "Number" + }, + { + "name": "distinct_id", + "description": "The current unique id", + "isOptional": true, + "type": "str" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Alias user", + "code": "# Alias user\nfrom posthog import alias\nalias(previous_id='distinct_id', distinct_id='alias_id')" + } + ] + }, + { + "id": "capture", + "title": "capture", + "description": "Capture anything a user does within your system.", + "details": "Capture allows you to capture anything a user does within your system, which you can later use in PostHog to find patterns in usage, work out which features to improve or where people are giving up. A capture call requires an event name to specify the event. We recommend using [verb] [noun], like `movie played` or `movie updated` to easily identify what your events mean later on. Capture takes a number of optional arguments, which are defined by the `OptionalCaptureArgs` type.", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name to specify the event **kwargs: Optional arguments including:", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Context and capture usage", + "code": "# Context and capture usage\nfrom posthog import new_context, identify_context, tag_context, capture\n# Enter a new context (e.g. a request/response cycle, an instance of a background job, etc)\nwith new_context():\n # Associate this context with some user, by distinct_id\n identify_context('some user')\n\n # Capture an event, associated with the context-level distinct ID ('some user')\n capture('movie started')\n\n # Capture an event associated with some other user (overriding the context-level distinct ID)\n capture('movie joined', distinct_id='some-other-user')\n\n # Capture an event with some properties\n capture('movie played', properties={'movie_id': '123', 'category': 'romcom'})\n\n # Capture an event with some properties\n capture('purchase', properties={'product_id': '123', 'category': 'romcom'})\n # Capture an event with some associated group\n capture('purchase', groups={'company': 'id:5'})\n\n # Adding a tag to the current context will cause it to appear on all subsequent events\n tag_context('some-tag', 'some-value')\n\n capture('another-event') # Will be captured with `'some-tag': 'some-value'` in the properties dict" + }, + { + "id": "example_2", + "name": "Set event properties", + "code": "# Set event properties\nfrom posthog import capture\ncapture(\n \"user_signed_up\",\n distinct_id=\"distinct_id_of_the_user\",\n properties={\n \"login_type\": \"email\",\n \"is_free_trial\": \"true\"\n }\n)" + } + ] + }, + { + "id": "capture_ai", + "title": "capture_ai", + "description": "Capture an AI event on the dedicated AI capture endpoint. Beta: the signature is stable; operational limits (per-event size cap, batching, endpoint) may change without notice. Takes the same arguments and returns the same value as `capture()`: the event UUID, or None when the event was not admitted (disabled client, or dropped by `before_send`). The event is delivered on an isolated queue with its own consumer pool and a higher per-event size cap, posting to the dedicated AI ingestion endpoint. The payload is sent as given \u2014 no redaction or truncation is applied here.", + "details": "", + "category": "Events", + "params": [ + { + "name": "event", + "description": "The event name, normally one of the `$ai_*` event names. **kwargs: Same optional arguments as `capture()`.", + "isOptional": true, + "type": "str" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import capture_ai\n\nuuid = capture_ai(\n \"$ai_generation\",\n distinct_id=\"user_123\",\n properties={\"$ai_model\": \"gpt-5\"},\n)" + } + ] + }, + { + "id": "capture_exception", + "title": "capture_exception", + "description": "Capture exceptions that happen in your code.", + "details": "Capture exception is idempotent - if it is called twice with the same exception instance, only a occurrence will be tracked in posthog. This is because, generally, contexts will cause exceptions to be captured automatically. However, to ensure you track an exception, if you catch and do not re-raise it, capturing it manually is recommended, unless you are certain it will have crossed a context boundary (e.g. by existing a `with posthog.new_context():` block already). If the passed exception was raised and caught, the captured stack trace will consist of every frame between where the exception was raised and the point at which it is captured (the \"traceback\"). If the passed exception was never raised, e.g. if you call `posthog.capture_exception(ValueError(\"Some Error\"))`, the stack trace captured will be the full stack trace at the moment the exception was captured. Note that heavy use of contexts will lead to truncated stack traces, as the exception will be captured by the context entered most recently, which may not be the point you catch the exception for the final time in your code. It's recommended to use contexts sparingly, for this reason. `capture_exception` takes the same set of optional arguments as `capture`.", + "category": "Events", + "params": [ + { + "name": "exception", + "description": "The exception to capture. If not provided, the current exception is captured via `sys.exc_info()` **kwargs: Optional capture arguments including distinct_id, properties, timestamp, uuid, groups, flags, send_feature_flags, and disable_geoip. Overriding reserved exception properties through ``properties`` is deprecated and will stop working in the next major version.", + "isOptional": false, + "type": "BaseException" + }, + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalCaptureArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Capture exception", + "code": "# Capture exception\nfrom posthog import capture_exception\ntry:\n risky_operation()\nexcept Exception as e:\n capture_exception(e)" + } + ] + }, + { + "id": "evaluate_flags", + "title": "evaluate_flags", + "description": "Evaluate all feature flags for a user in a single call and return a :class:`FeatureFlagEvaluations` snapshot. Branch on ``.is_enabled()`` / ``.get_flag()`` and pass the same snapshot to ``capture()`` via the ``flags`` option so events carry the exact flag values the code branched on. Prefer this over repeated ``get_feature_flag()`` calls and over ``capture(send_feature_flags=True)`` \u2014 it consolidates flag evaluation into a single ``/flags`` request per incoming request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID. If ``None``, falls back to the context distinct_id. If still unresolvable, returns an empty snapshot.", + "isOptional": false, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "If ``True``, never fall back to remote evaluation and omit flags that cannot be evaluated locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "flag_keys", + "description": "Optional list that scopes local evaluation, the underlying ``/flags`` request, and the returned snapshot. When omitted or ``None``, all flags are evaluated. An empty list returns an empty snapshot without evaluating flags. A requested key absent from loaded local definitions is included in one remote fallback per ``evaluate_flags`` call unless ``only_evaluate_locally`` is ``True``. If the server also does not know the key, it is omitted from the snapshot.", + "isOptional": true, + "type": "list[str]" + }, + { + "name": "device_id", + "description": "Optional device ID override. If not provided, falls back to the context device_id (which may be set via tracing headers). Used by experience-continuity flags to match users across distinct_id changes.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FeatureFlagEvaluations" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import evaluate_flags, capture\nflags = evaluate_flags(\"user_123\", person_properties={\"plan\": \"enterprise\"})\nif flags.is_enabled(\"new-dashboard\"):\n render_new_dashboard()\ncapture(\"page_viewed\", distinct_id=\"user_123\", flags=flags)" + } + ] + }, + { + "id": "feature_enabled", + "title": "feature_enabled", + "description": "Use feature flags to enable or disable features for users.", + "details": "You can call `posthog.load_feature_flags()` before to make sure you're not doing unexpected requests.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[bool]" + }, + "examples": [ + { + "id": "example_1", + "name": "Boolean feature flag", + "code": "# Boolean feature flag\nfrom posthog import feature_enabled, get_feature_flag_payload\nis_my_flag_enabled = feature_enabled('flag-key', 'distinct_id_of_your_user')\nif is_my_flag_enabled:\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "feature_flag_definitions", + "title": "feature_flag_definitions", + "description": "Returns loaded feature flags.", + "details": "Returns loaded feature flags, if any. Helpful for debugging what flag information you have loaded.", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import feature_flag_definitions\ndefinitions = feature_flag_definitions()" + } + ] + }, + { + "id": "flush", + "title": "flush", + "description": "Attempt immediate delivery of queued events and ended spans, keeping the global client reusable. Call ``flush()`` before a short-lived request or serverless invocation returns when using the shared module-level client. Use ``shutdown()`` only for final process cleanup or a client that will not be reused. Flush does not stop the background workers or feature flag poller, and does not end open spans. Returning does not guarantee server receipt: pending work can remain after a timeout or span export failure, and failed events may be dropped by consumers. Calls made directly from SDK callbacks such as ``on_error`` are deferred rather than blocking the worker that invoked the callback.", + "details": "", + "category": "Client management", + "params": [ + { + "name": "timeout_seconds", + "description": "Seconds to wait for event queues to drain, shared across event lanes. Defaults to 10 seconds. Pass ``None`` to wait without a time limit; this does not guarantee successful delivery. Queued spans flush concurrently, waiting up to this many seconds for an in-flight flush before starting a fresh drain budget. A lock wait timeout leaves the in-flight flush to finish. At least one span request is attempted after acquiring the lock, even with no budget left; retriable failures are retried after backoff while budget remains, with one last attempt at the deadline. The last span request is not cut short and is bounded by the client's ``timeout`` in seconds, so this is not a strict wall-clock limit for the whole call. With ``None``, a retriable span failure is left for a later flush rather than retried within this call.", + "isOptional": true, + "type": "float" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.capture('event_name', distinct_id='user_id')\n# Before a serverless invocation returns; keep the global client open.\nposthog.flush(timeout_seconds=10)" + } + ] + }, + { + "id": "get_active_span", + "title": "get_active_span", + "description": "The span that is active in the current context, or ``None``. Alpha. Only entering a span (``with posthog.start_span(...) as span:``) makes it active; a span started manually is not. Use it to propagate the trace to the next service: ``span.traceparent()`` is the header value.", + "details": "", + "category": "Tracing", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[Span]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "span = posthog.get_active_span()\nif span is not None:\n headers[\"traceparent\"] = span.traceparent()" + } + ] + }, + { + "id": "get_all_flags", + "title": "get_all_flags", + "description": "Get all flags for a given user.", + "details": "Flags are key-value pairs where the key is the flag key and the value is the flag variant, or True, or False.", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate (evaluates all if None)", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[dict[str, Union[bool, str]]]" + }, + "examples": [ + { + "id": "example_1", + "name": "All flags for user", + "code": "# All flags for user\nfrom posthog import get_all_flags\nget_all_flags('distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_all_flags_and_payloads", + "title": "get_all_flags_and_payloads", + "description": "Get all feature flag values and payloads for a user.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + }, + { + "name": "flag_keys_to_evaluate", + "description": "Optional list of flag keys to evaluate. Evaluates all flags when omitted.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "FlagsAndPayloads" + } + }, + { + "id": "get_feature_flag", + "title": "get_feature_flag", + "description": "Get feature flag variant for users. Used with experiments.", + "details": "`groups` are a mapping from group type to group key. So, if you have a group type of \"organization\" and a group key of \"5\", you would pass groups={\"organization\": \"5\"}. `group_properties` take the format: { group_type_name: { group_properties } }. So, for example, if you have the group type \"organization\" and the group key \"5\", with the properties name, and employee count, you'll send these as: group_properties={\"organization\": {\"name\": \"PostHog\", \"employees\": 11}}.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Groups mapping from group type to group key", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties in format { group_type_name: { group_properties } }", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send feature flag events", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Union[bool, str, any]" + }, + "examples": [ + { + "id": "example_1", + "name": "Multivariate feature flag", + "code": "# Multivariate feature flag\nfrom posthog import get_feature_flag, get_feature_flag_payload\nenabled_variant = get_feature_flag('flag-key', 'distinct_id_of_your_user')\nif enabled_variant == 'variant-key':\n matched_flag_payload = get_feature_flag_payload('flag-key', 'distinct_id_of_your_user')" + } + ] + }, + { + "id": "get_feature_flag_evaluation_runtime", + "title": "get_feature_flag_evaluation_runtime", + "description": "Return where a locally loaded feature flag is meant to be evaluated.", + "details": "Reads the `evaluation_runtime` each flag definition carries, so no extra request is made. Returns `None` when local evaluation has not loaded a definition for this key. A definition that carries no runtime reports `FeatureFlagEvaluationRuntime.ALL`, the default PostHog applies.", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagEvaluationRuntime]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_evaluation_runtime\nruntime = get_feature_flag_evaluation_runtime(\"my-flag\")" + } + ] + }, + { + "id": "get_feature_flag_keys_by_evaluation_runtime", + "title": "get_feature_flag_keys_by_evaluation_runtime", + "description": "Return the keys of locally loaded flags that a runtime can evaluate.", + "details": "A flag set to `FeatureFlagEvaluationRuntime.ALL` suits either runtime, so it is returned for `CLIENT` and for `SERVER`. Use this to decide which flags to hand to a browser when a backend serves flags to its own frontend.", + "category": "Feature flags", + "params": [ + { + "name": "evaluation_runtime", + "description": "", + "isOptional": true, + "type": "FeatureFlagEvaluationRuntime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "list[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import FeatureFlagEvaluationRuntime, get_feature_flag_keys_by_evaluation_runtime\nclient_keys = get_feature_flag_keys_by_evaluation_runtime(FeatureFlagEvaluationRuntime.CLIENT)" + } + ] + }, + { + "id": "get_feature_flag_payload", + "title": "get_feature_flag_payload", + "description": "Get the payload associated with a feature flag value. Deprecated for new code. Prefer ``evaluate_flags()`` and ``flags.get_flag_payload(key)`` so flag evaluation happens once per request.", + "details": "", + "category": "Feature flags", + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "match_value", + "description": "Optional flag value to use when selecting a payload.", + "isOptional": false, + "type": "bool" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[object]" + } + }, + { + "id": "get_feature_flag_result", + "title": "get_feature_flag_result", + "description": "Get a FeatureFlagResult object which contains the flag result and payload. This method evaluates a feature flag and returns a FeatureFlagResult object containing: - enabled: Whether the flag is enabled - variant: The variant value if the flag has variants - payload: The payload associated with the flag (automatically deserialized from JSON) - key: The flag key - reason: Why the flag was enabled/disabled", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The feature flag key.", + "isOptional": true, + "type": "str" + }, + { + "name": "distinct_id", + "description": "The user's distinct ID.", + "isOptional": true, + "type": "Number" + }, + { + "name": "groups", + "description": "Mapping of group type to group key.", + "isOptional": true, + "type": "Mapping[str, Union[str, int]]" + }, + { + "name": "person_properties", + "description": "Person properties to use for evaluation.", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "group_properties", + "description": "Group properties keyed by group type.", + "isOptional": true, + "type": "dict[str, dict[str, Any]]" + }, + { + "name": "only_evaluate_locally", + "description": "Whether to evaluate only locally.", + "isOptional": false, + "type": "bool" + }, + { + "name": "send_feature_flag_events", + "description": "Whether to send a $feature_flag_called event.", + "isOptional": false, + "type": "bool" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup.", + "isOptional": true, + "type": "bool" + }, + { + "name": "device_id", + "description": "Optional device ID override for experience-continuity flags.", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[FeatureFlagResult]" + } + }, + { + "id": "get_remote_config_payload", + "title": "get_remote_config_payload", + "description": "Get the payload for a remote config feature flag.", + "details": "", + "category": null, + "params": [ + { + "name": "key", + "description": "The key of the feature flag", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "get_tags", + "title": "get_tags", + "description": "Get all tags from the current context. Returns: Dict of all tags in the current context", + "details": "", + "category": "Contexts", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "dict[str, Any]" + } + }, + { + "id": "group_identify", + "title": "group_identify", + "description": "Set properties on a group.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "group_type", + "description": "Type of your group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "group_key", + "description": "Unique identifier of the group. Required - the call is dropped with a warning if it is missing or empty.", + "isOptional": true, + "type": "str" + }, + { + "name": "properties", + "description": "Properties to set on the group", + "isOptional": true, + "type": "dict[str, Any]" + }, + { + "name": "timestamp", + "description": "Optional timestamp for the event. UTC is preferred; non-UTC datetimes and parseable ISO timestamp strings are converted to UTC.", + "isOptional": false, + "type": "datetime" + }, + { + "name": "uuid", + "description": "Optional UUID for the event", + "isOptional": true, + "type": "str" + }, + { + "name": "disable_geoip", + "description": "Whether to disable GeoIP lookup", + "isOptional": true, + "type": "bool" + }, + { + "name": "distinct_id", + "description": "Optional distinct ID of the user performing the action", + "isOptional": false, + "type": "Number" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Group identify", + "code": "# Group identify\nfrom posthog import group_identify\ngroup_identify('company', 'company_id_in_your_db', {\n 'name': 'Awesome Inc.',\n 'employees': 11\n})" + } + ] + }, + { + "id": "identify_context", + "title": "identify_context", + "description": "Identify the current context with a distinct ID.", + "details": "", + "category": "Identification", + "params": [ + { + "name": "distinct_id", + "description": "The distinct ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import identify_context\nidentify_context(\"user_123\")" + } + ] + }, + { + "id": "join", + "title": "join", + "description": "Attempt to process queued events and stop the client's background workers. Use `shutdown()` directly in most cases. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import join\njoin()" + } + ] + }, + { + "id": "load_feature_flags", + "title": "load_feature_flags", + "description": "Load feature flag definitions from PostHog.", + "details": "", + "category": "Feature flags", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import load_feature_flags\nload_feature_flags()" + } + ] + }, + { + "id": "new_context", + "title": "new_context", + "description": "Create a new context scope that will be active for the duration of the with block.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture exceptions raised within the context. If omitted, defaults to the relevant client's exception autocapture setting.", + "isOptional": true, + "type": "bool" + }, + { + "name": "client", + "description": "Optional Posthog client instance to use for this context (default: None)", + "isOptional": true, + "type": "Client" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import new_context, tag, capture\nwith new_context():\n tag(\"request_id\", \"123\")\n capture(\"event_name\", properties={\"property\": \"value\"})" + } + ] + }, + { + "id": "scoped", + "title": "scoped", + "description": "Decorator that creates a new context for the function.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "fresh", + "description": "Whether to start with a fresh context (default: False)", + "isOptional": false, + "type": "bool" + }, + { + "name": "capture_exceptions", + "description": "Whether to capture and track exceptions with posthog error tracking. If omitted, defaults to the global exception autocapture setting.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import scoped, tag, capture\n@scoped()\ndef process_payment(payment_id):\n tag(\"payment_id\", payment_id)\n capture(\"payment_started\")" + } + ] + }, + { + "id": "set", + "title": "set", + "description": "Set properties on a user record.", + "details": "This will overwrite previous people property values. Generally operates similar to `capture`, with distinct_id being an optional argument, defaulting to the current context's distinct ID. If there is no context-level distinct ID, and no override distinct_id is passed, this function will do nothing. Context tags are folded into $set properties, so tagging the current context and then calling `set` will cause those tags to be set on the user (unlike capture, which causes them to just be set on the event).", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set person properties", + "code": "# Set person properties\nfrom posthog import set\nset(distinct_id='distinct_id', properties={'name': 'Max Hedgehog'})" + } + ] + }, + { + "id": "set_capture_exception_code_variables_context", + "title": "set_capture_exception_code_variables_context", + "description": "Override code-variable capture for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "Whether exceptions captured in this context should include local variable values from stack frames.", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_detect_secrets_context", + "title": "set_code_variables_detect_secrets_context", + "description": "Whether to apply entropy-based secret detection as a last-resort redaction of high-entropy values (API keys, tokens, strong passwords) in captured code variables for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_ignore_patterns_context", + "title": "set_code_variables_ignore_patterns_context", + "description": "Override code-variable ignore patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "ignore_patterns", + "description": "Variable-name patterns that should be omitted entirely when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_patterns_context", + "title": "set_code_variables_mask_patterns_context", + "description": "Override code-variable mask patterns for exceptions in the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "mask_patterns", + "description": "Variable-name patterns whose values should be replaced with ``***`` when code variables are captured.", + "isOptional": true, + "type": "list[str]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_code_variables_mask_url_credentials_context", + "title": "set_code_variables_mask_url_credentials_context", + "description": "Whether to scrub credentials embedded in URLs/DSNs (e.g. user:pass@host) from captured code variables for the current context.", + "details": "", + "category": null, + "params": [ + { + "name": "enabled", + "description": "", + "isOptional": true, + "type": "bool" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + } + }, + { + "id": "set_context_device_id", + "title": "set_context_device_id", + "description": "Set the device ID for the current context, associating all feature flag requests in this or child contexts with the given device ID.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "device_id", + "description": "The device ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_device_id\nset_context_device_id(\"device_123\")" + } + ] + }, + { + "id": "set_context_session", + "title": "set_context_session", + "description": "Set the session ID for the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "session_id", + "description": "The session ID to associate with the current context and its children", + "isOptional": true, + "type": "str" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import set_context_session\nset_context_session(\"session_123\")" + } + ] + }, + { + "id": "set_once", + "title": "set_once", + "description": "Set properties on a user record, only if they do not yet exist.", + "details": "This will not overwrite previous people property values, unlike `set`. Otherwise, operates in an identical manner to `set`.", + "category": "Identification", + "params": [ + { + "name": "kwargs", + "description": "", + "isOptional": true, + "type": "Unpack[OptionalSetArgs]" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Optional[str]" + }, + "examples": [ + { + "id": "example_1", + "name": "Set property once", + "code": "# Set property once\nfrom posthog import set_once\nset_once(distinct_id='distinct_id', properties={'initial_url': '/blog'})" + } + ] + }, + { + "id": "setup", + "title": "setup", + "description": "Create or return the global PostHog client configured by module settings. Most applications should either instantiate ``Posthog`` directly or set ``posthog.api_key``/other module settings before calling top-level helpers. ``setup()`` is called automatically by global APIs such as ``capture()``. Returns: The global ``Client`` instance. If both ``api_key`` and ``project_api_key`` are missing or blank, the client is disabled and module-level calls become no-ops.", + "details": "", + "category": "Initialization", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Client" + } + }, + { + "id": "shutdown", + "title": "shutdown", + "description": "Attempt final delivery and permanently shut down the global client. Call this for final process cleanup, not at the end of each request or serverless invocation that shares the module-level client. Use ``flush()`` before returning from those invocations instead. Shutdown closes capture lanes, stops background workers and the feature flag poller, and tears down integrations. The global client is not recreated automatically after shutdown. This normally blocks until queued events have been attempted and cleanup finishes. Failed or undrainable events may be dropped and reported through logging or ``on_error``; returning does not guarantee server receipt. Event draining has no timeout. Queued spans get a final flush with up to 30 seconds waiting for an in-flight flush, then a fresh 30-second drain budget; the last HTTP request is not cut short. Unsent queued spans and still-open spans are discarded with a warning. Lifecycle cleanup is attempted once, and cleanup failures are logged without retry. Calls made directly from SDK callbacks such as ``on_error`` are deferred to avoid deadlocking the worker. If blocking completion is required, signal an application-owned thread, return from the callback, and call ``shutdown()`` from that thread. Do not wait inside a callback for another thread or task calling a lifecycle method.", + "details": "", + "category": "Client management", + "params": [], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "any" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import shutdown\nshutdown()" + } + ] + }, + { + "id": "start_span", + "title": "start_span", + "description": "Start a span for distributed tracing. Alpha. Returns a span handle. Use it as a context manager to make it the active span for the block and end it on exit (recording a raised exception on the way out); or call ``end()`` yourself for a span that cannot wrap a block. Spans started inside the block nest under it automatically. Always returns a usable handle, even when tracing is off, so calling code never branches.", + "details": "", + "category": "Tracing", + "params": [ + { + "name": "name", + "description": "A low-cardinality operation name, e.g. ``GET /users/:id``. Variable values belong in attributes, not the name.", + "isOptional": true, + "type": "str" + }, + { + "name": "kind", + "description": "``internal`` (default), ``server``, ``client``, ``producer`` or ``consumer``.", + "isOptional": true, + "type": "str" + }, + { + "name": "attributes", + "description": "Initial attributes.", + "isOptional": true, + "type": "Mapping[str, Any]" + }, + { + "name": "parent", + "description": "A span handle, or an inbound W3C ``traceparent`` header value to continue a remote trace. Defaults to the active span.", + "isOptional": false, + "type": "Span" + }, + { + "name": "tracestate", + "description": "The inbound ``tracestate`` header accompanying a ``traceparent`` string ``parent``; preserved and propagated.", + "isOptional": true, + "type": "str" + }, + { + "name": "start_time", + "description": "A ``datetime`` or epoch seconds, to backdate the span.", + "isOptional": false, + "type": "datetime" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "Span" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "import posthog\nposthog.traces = {\"service_name\": \"checkout-api\"}\n\nwith posthog.start_span(\"POST /checkout\", parent=request.headers.get(\"traceparent\")) as span:\n span.set_attribute(\"plan\", user.plan)\n with posthog.start_span(\"db.query\", kind=\"client\"):\n ...\n outgoing_headers = {\"traceparent\": span.traceparent()}" + } + ] + }, + { + "id": "tag", + "title": "tag", + "description": "Add a tag to the current context.", + "details": "", + "category": "Contexts", + "params": [ + { + "name": "name", + "description": "The tag key", + "isOptional": true, + "type": "str" + }, + { + "name": "value", + "description": "The tag value", + "isOptional": true, + "type": "Any" + } + ], + "showDocs": true, + "releaseTag": "public", + "returnType": { + "id": "return_type", + "name": "None" + }, + "examples": [ + { + "id": "example_1", + "name": "Example 1", + "code": "from posthog import tag\ntag(\"user_id\", \"123\")" + } + ] + } + ] + } + ], + "categories": [ + "Initialization", + "Identification", + "Capture", + "Error Tracking", + "Feature flags", + "Tracing", + "Contexts", + "Events", + "Client management" + ] +} \ No newline at end of file diff --git a/references/posthog-python-references-latest.json b/references/posthog-python-references-latest.json index 342f66487..ecbda11e3 100644 --- a/references/posthog-python-references-latest.json +++ b/references/posthog-python-references-latest.json @@ -2,7 +2,7 @@ "id": "posthog-python", "hogRef": "0.3", "info": { - "version": "7.75.5", + "version": "7.75.6", "id": "posthog-python", "title": "PostHog Python SDK", "description": "Integrate PostHog into any python application.", From c872436249585539dab10a44a7b85343c8d37f59 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi <3247106+gantoine@users.noreply.github.com> Date: Thu, 22 Oct 2026 15:05:41 -0400 Subject: [PATCH 69/70] chore(deps): bump uv to 0.13.4 and certifi to 2026.10.19 (#1104) Bump uv to 0.13.4 and certifi to 2026.10.19 Eight eMudhra intermediate CA private keys were broken, so anyone holding them can impersonate TLS servers to clients that still trust emSign ECC Root CA - G3. uv 0.13.4 and certifi 2026.10.19 are the first releases whose bundled CA store drops that root, and the versions pinned here still trust it. See the Python.org notice. https://discuss.python.org/t/information-for-python-users-regarding-emudhra-emsign-ca-certificate-security-incident/109576 Claude-Session: https://claude.ai/code/session_01T4ck1tYoQv3mzBTXH17asD Co-authored-by: Claude (cherry picked from commit 7651b10da2d3594de0dbd808883c5a7f2e5398e8) --- .github/actions/setup-python-dev/action.yml | 2 +- .github/workflows/ci.yml | 12 ++-- .github/workflows/posthog-upgrade.yml | 2 +- .github/workflows/release.yml | 6 +- examples/example-ai-anthropic/uv.lock | 18 ++++-- examples/example-ai-anthropic/uv.toml | 2 + examples/example-ai-autogen/uv.lock | 18 ++++-- examples/example-ai-autogen/uv.toml | 2 + examples/example-ai-aws-bedrock/uv.lock | 18 ++++-- examples/example-ai-aws-bedrock/uv.toml | 2 + examples/example-ai-azure-openai/uv.lock | 18 ++++-- examples/example-ai-azure-openai/uv.toml | 2 + examples/example-ai-cerebras/uv.lock | 18 ++++-- examples/example-ai-cerebras/uv.toml | 2 + .../example-ai-cloudflare-ai-gateway/uv.lock | 18 ++++-- .../example-ai-cloudflare-ai-gateway/uv.toml | 2 + examples/example-ai-cohere/uv.lock | 18 ++++-- examples/example-ai-cohere/uv.toml | 2 + examples/example-ai-crewai/uv.lock | 56 ++++++++++--------- examples/example-ai-crewai/uv.toml | 2 + examples/example-ai-dedalus/uv.lock | 18 ++++-- examples/example-ai-dedalus/uv.toml | 2 + examples/example-ai-deepseek/uv.lock | 18 ++++-- examples/example-ai-deepseek/uv.toml | 2 + examples/example-ai-dspy/uv.lock | 11 ++-- examples/example-ai-dspy/uv.toml | 2 + examples/example-ai-fireworks-ai/uv.lock | 18 ++++-- examples/example-ai-fireworks-ai/uv.toml | 2 + examples/example-ai-gemini/uv.lock | 18 ++++-- examples/example-ai-gemini/uv.toml | 2 + examples/example-ai-groq/uv.lock | 18 ++++-- examples/example-ai-groq/uv.toml | 2 + examples/example-ai-helicone/uv.lock | 18 ++++-- examples/example-ai-helicone/uv.toml | 2 + examples/example-ai-hugging-face/uv.lock | 18 ++++-- examples/example-ai-hugging-face/uv.toml | 2 + examples/example-ai-instructor/uv.lock | 16 ++++-- examples/example-ai-instructor/uv.toml | 2 + examples/example-ai-langchain/uv.lock | 18 ++++-- examples/example-ai-langchain/uv.toml | 2 + examples/example-ai-langgraph/uv.lock | 18 ++++-- examples/example-ai-langgraph/uv.toml | 2 + examples/example-ai-litellm/uv.lock | 11 ++-- examples/example-ai-litellm/uv.toml | 2 + examples/example-ai-llamaindex/uv.lock | 16 ++++-- examples/example-ai-llamaindex/uv.toml | 2 + examples/example-ai-mirascope/uv.lock | 18 ++++-- examples/example-ai-mirascope/uv.toml | 2 + examples/example-ai-mistral/uv.lock | 18 ++++-- examples/example-ai-mistral/uv.toml | 2 + examples/example-ai-ollama/uv.lock | 18 ++++-- examples/example-ai-ollama/uv.toml | 2 + examples/example-ai-openai-agents/uv.lock | 11 ++-- examples/example-ai-openai-agents/uv.toml | 2 + examples/example-ai-openai/uv.lock | 18 ++++-- examples/example-ai-openai/uv.toml | 2 + examples/example-ai-openrouter/uv.lock | 18 ++++-- examples/example-ai-openrouter/uv.toml | 2 + examples/example-ai-perplexity/uv.lock | 18 ++++-- examples/example-ai-perplexity/uv.toml | 2 + examples/example-ai-portkey/uv.lock | 18 ++++-- examples/example-ai-portkey/uv.toml | 2 + examples/example-ai-pydantic-ai/uv.lock | 16 ++++-- examples/example-ai-pydantic-ai/uv.toml | 2 + examples/example-ai-semantic-kernel/uv.lock | 16 ++++-- examples/example-ai-semantic-kernel/uv.toml | 2 + examples/example-ai-smolagents/uv.lock | 18 ++++-- examples/example-ai-smolagents/uv.toml | 2 + examples/example-ai-together-ai/uv.lock | 18 ++++-- examples/example-ai-together-ai/uv.toml | 2 + examples/example-ai-vercel-ai-gateway/uv.lock | 18 ++++-- examples/example-ai-vercel-ai-gateway/uv.toml | 2 + examples/example-ai-xai/uv.lock | 18 ++++-- examples/example-ai-xai/uv.toml | 2 + integration_tests/django5/pyproject.toml | 2 + integration_tests/django5/uv.lock | 16 ++++-- .../fastapi-async-client/pyproject.toml | 2 + playgrounds/fastapi-async-client/uv.lock | 18 ++++-- pyproject.toml | 2 + uv.lock | 9 ++- 80 files changed, 563 insertions(+), 217 deletions(-) diff --git a/.github/actions/setup-python-dev/action.yml b/.github/actions/setup-python-dev/action.yml index 863d5abef..347ebeafd 100644 --- a/.github/actions/setup-python-dev/action.yml +++ b/.github/actions/setup-python-dev/action.yml @@ -18,7 +18,7 @@ runs: - name: Install uv uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install dev dependencies diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f92d5194d..92334514d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,7 +111,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Build and verify distributions @@ -139,7 +139,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install test dependencies @@ -178,7 +178,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install test dependencies @@ -244,7 +244,7 @@ jobs: if: steps.changes.outputs.changed == 'true' uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Check utils CRAP score @@ -325,7 +325,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true # openfeature-provider-posthog is a uv workspace member (declared in @@ -380,7 +380,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install Django 5 test project dependencies diff --git a/.github/workflows/posthog-upgrade.yml b/.github/workflows/posthog-upgrade.yml index 585f2958b..0c1f8126f 100644 --- a/.github/workflows/posthog-upgrade.yml +++ b/.github/workflows/posthog-upgrade.yml @@ -44,7 +44,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.12.21" + version: "0.13.4" - name: Install new package version in main repo shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2de109583..e8afa85bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,7 +103,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install Rust @@ -308,7 +308,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install dependencies @@ -475,7 +475,7 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0 with: - version: "0.11.32" + version: "0.13.4" enable-cache: true - name: Install Rust diff --git a/examples/example-ai-anthropic/uv.lock b/examples/example-ai-anthropic/uv.lock index 88660457b..2162e2894 100644 --- a/examples/example-ai-anthropic/uv.lock +++ b/examples/example-ai-anthropic/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -59,11 +62,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -523,7 +526,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.62.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -542,12 +545,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -569,6 +576,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-anthropic/uv.toml b/examples/example-ai-anthropic/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-anthropic/uv.toml +++ b/examples/example-ai-anthropic/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-autogen/uv.lock b/examples/example-ai-autogen/uv.lock index 639ed6ea7..24352e92e 100644 --- a/examples/example-ai-autogen/uv.lock +++ b/examples/example-ai-autogen/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiofiles" version = "25.1.0" @@ -97,11 +100,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -673,7 +676,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -692,12 +695,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -719,6 +726,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-autogen/uv.toml b/examples/example-ai-autogen/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-autogen/uv.toml +++ b/examples/example-ai-autogen/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-aws-bedrock/uv.lock b/examples/example-ai-aws-bedrock/uv.lock index 3d0ba6589..002c854bd 100644 --- a/examples/example-ai-aws-bedrock/uv.lock +++ b/examples/example-ai-aws-bedrock/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "backoff" version = "2.2.1" @@ -45,11 +48,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -362,7 +365,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -381,12 +384,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -408,6 +415,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-aws-bedrock/uv.toml b/examples/example-ai-aws-bedrock/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-aws-bedrock/uv.toml +++ b/examples/example-ai-aws-bedrock/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-azure-openai/uv.lock b/examples/example-ai-azure-openai/uv.lock index 8869e9e36..887d67488 100644 --- a/examples/example-ai-azure-openai/uv.lock +++ b/examples/example-ai-azure-openai/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-azure-openai/uv.toml b/examples/example-ai-azure-openai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-azure-openai/uv.toml +++ b/examples/example-ai-azure-openai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-cerebras/uv.lock b/examples/example-ai-cerebras/uv.lock index 8e6ac73fd..ef3100dc7 100644 --- a/examples/example-ai-cerebras/uv.lock +++ b/examples/example-ai-cerebras/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-cerebras/uv.toml b/examples/example-ai-cerebras/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-cerebras/uv.toml +++ b/examples/example-ai-cerebras/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-cloudflare-ai-gateway/uv.lock b/examples/example-ai-cloudflare-ai-gateway/uv.lock index 98e60b5af..fad13fdb0 100644 --- a/examples/example-ai-cloudflare-ai-gateway/uv.lock +++ b/examples/example-ai-cloudflare-ai-gateway/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-cloudflare-ai-gateway/uv.toml b/examples/example-ai-cloudflare-ai-gateway/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-cloudflare-ai-gateway/uv.toml +++ b/examples/example-ai-cloudflare-ai-gateway/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-cohere/uv.lock b/examples/example-ai-cohere/uv.lock index a48b30504..0e7c2a2a9 100644 --- a/examples/example-ai-cohere/uv.lock +++ b/examples/example-ai-cohere/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-cohere/uv.toml b/examples/example-ai-cohere/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-cohere/uv.toml +++ b/examples/example-ai-cohere/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-crewai/uv.lock b/examples/example-ai-crewai/uv.lock index a7fb05dfa..8589391ee 100644 --- a/examples/example-ai-crewai/uv.lock +++ b/examples/example-ai-crewai/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14'", @@ -13,6 +13,10 @@ resolution-markers = [ exclude-newer = "2026-10-03T03:16:06.117367Z" exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } +uv = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -399,11 +403,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -3929,28 +3933,28 @@ wheels = [ [[package]] name = "uv" -version = "0.11.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/34/609d5d01ba21dc8f0974610ca7802fbb2c946a0c38665cfe5c5aeddbefb5/uv-0.11.15.tar.gz", hash = "sha256:755f959ec6a2fd8ccb6ee76ad90ab759d2eb1f4797444078645dd1ee4bca92d6", size = 4159545, upload-time = "2026-05-18T19:57:48.133Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/7c/dcc230c5911884d8848145dabcac8fb95a5ed6f9fe1c57fae8242618f28a/uv-0.11.15-py3-none-linux_armv6l.whl", hash = "sha256:83b04ab49514a0a761ffedb36a748ee81f87746671e72088e5f32c9585e5f1a9", size = 23110183, upload-time = "2026-05-18T19:57:23.051Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f3/efd4e044b60eb9c3c12ee386be098d56c335538ccec7caa49349cfba9344/uv-0.11.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b6cae61f737be075b90be9e3f07d961072aed7019f4c9b8ed5c5d41c4d6cade3", size = 22637941, upload-time = "2026-05-18T19:57:26.752Z" }, - { url = "https://files.pythonhosted.org/packages/a6/b8/48627f895a1569e576822e0a8416aa4797eb4a4551de21a4ad97b9b5819d/uv-0.11.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9accae33619a9166e5c48531deb455d672cfb89f9357a00975e669c76b0bd49f", size = 21258803, upload-time = "2026-05-18T19:57:05.473Z" }, - { url = "https://files.pythonhosted.org/packages/af/50/4bc8a148274feabee2d9c9f1fa15009e10c0228dfe57981ee3ea2ef1d481/uv-0.11.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:c0cf52cd6d50bb9e05e2d968f45f80761107e4cbc8d4a26d9758f9d8274aaec1", size = 23066178, upload-time = "2026-05-18T19:57:33.058Z" }, - { url = "https://files.pythonhosted.org/packages/a9/56/139fc3bec9a8b0a25bfe2196123adb9f16124da437bf4fbcf0d21cfcafb2/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:49dc6ed70bff00937384f96cdc4b1a4742d18e5504ec2c4a1214dba2dee5687a", size = 22705332, upload-time = "2026-05-18T19:57:36.714Z" }, - { url = "https://files.pythonhosted.org/packages/ca/b0/b18b3dd204f8c213236a1ebd148e009861637129a8cce34df0e9aa22ed40/uv-0.11.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:adb9a89352539fdd8f7cd5f9966cf9f94fc5b98e0ccdf5003a04123dc6423bec", size = 22707534, upload-time = "2026-05-18T19:58:04.117Z" }, - { url = "https://files.pythonhosted.org/packages/76/36/3ca09f95572df99d361b49c96b1297149e96e120d8d1ecf074095a4b6da4/uv-0.11.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40ff67e3f8e8a7533781a2e892a534975a93acb83ea35460e64e7b2bf2111774", size = 24096607, upload-time = "2026-05-18T19:58:11.625Z" }, - { url = "https://files.pythonhosted.org/packages/64/be/3bdee21a296bbf5336a526e3613d0e7d4538dacc39c62d7fcba55d15f6b0/uv-0.11.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6463a299ed7e6b5a800ed6f108af8e1588352629424133ddef7572b0e1e1118", size = 25082562, upload-time = "2026-05-18T19:57:40.69Z" }, - { url = "https://files.pythonhosted.org/packages/cd/73/f371f3689ffe741066468d001d85f739fc4b5574de83b639ef19b5e8a7f4/uv-0.11.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68c1e62d4b78578b90b833553286b65d6a7e327537716441068583ba652ec4f5", size = 24253391, upload-time = "2026-05-18T19:57:18.47Z" }, - { url = "https://files.pythonhosted.org/packages/d3/16/fe392d618af6b00c064b3e718d585dcf791546a77c5123a5bec07ce53a0a/uv-0.11.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98edf1bdaf82447014852051d93e3ee95012509c567bf057fd117e6bdbd9a807", size = 24415871, upload-time = "2026-05-18T19:58:19.651Z" }, - { url = "https://files.pythonhosted.org/packages/6e/24/2e92a052fb6334fcd746d1c7cb57847c204b118c84f5da53c0f9e129f7b7/uv-0.11.15-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:be8f76d25bcf4c92bb384240ac1bf9aa7f51063d0bdeca4c9cf0ec3ed8b145e0", size = 23159007, upload-time = "2026-05-18T19:57:10.653Z" }, - { url = "https://files.pythonhosted.org/packages/3d/2e/6923d0658d164bb2c435ed1868aa2d49b3074594679917a001ff92dc95bb/uv-0.11.15-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:f9f4fbbf4fe485522054f3c7496c6e8e932d6436e4200ff3daf718db0b7c7bd5", size = 23769385, upload-time = "2026-05-18T19:58:15.856Z" }, - { url = "https://files.pythonhosted.org/packages/a4/99/7e34cd949e57360814e8064cc9fb7104df445d0f6a663504e5f7473480aa/uv-0.11.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0ed920e896b2fd13a35031707e307e42fbb2681458b967440a17272d86d49137", size = 23860973, upload-time = "2026-05-18T19:57:55.575Z" }, - { url = "https://files.pythonhosted.org/packages/28/98/8fe1f5f9d816e94569a0298dd8e0936801097625fa1952162951f0d628b6/uv-0.11.15-py3-none-musllinux_1_1_i686.whl", hash = "sha256:41d907611f3e6a13262807fd7f0a17849f76285ca80f536f6b3943732bdc6656", size = 23431392, upload-time = "2026-05-18T19:57:59.814Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6b/76a1ce2fa860026913a5941700cdc7d715fce9c3277a3fa3489cf2523ca0/uv-0.11.15-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e3b68f8bf1a4568710f77e5bda9182ce7682811d89a8e7468c22460e032b234d", size = 24519478, upload-time = "2026-05-18T19:57:51.165Z" }, - { url = "https://files.pythonhosted.org/packages/43/60/1d58e8a05718cb50494763115710b73846cacb651fd735d285233fd72c59/uv-0.11.15-py3-none-win32.whl", hash = "sha256:8e2da3076761086a5b76869c3f38ef0509c836046ef41ddd19485dfd7271dca9", size = 22020178, upload-time = "2026-05-18T19:58:07.64Z" }, - { url = "https://files.pythonhosted.org/packages/55/53/40fcefcb348af660488597ed3c01363df7344e60611f8883750dc596f5c6/uv-0.11.15-py3-none-win_amd64.whl", hash = "sha256:cc3915ab291a1ecaf31de05f5d8bd70d09c66fe9911a53f70d9efa62ff0dbd8a", size = 24668779, upload-time = "2026-05-18T19:57:44.894Z" }, - { url = "https://files.pythonhosted.org/packages/e5/7d/fa3a9960c95af9bbe2a629048760d0b9b4fead8ccd4f2235af747ec7cdf0/uv-0.11.15-py3-none-win_arm64.whl", hash = "sha256:4f39426a13dee24897aed60c4b98058c66f18bd983885ac5f4a54a04b24fbddf", size = 23198178, upload-time = "2026-05-18T19:57:14.68Z" }, +version = "0.13.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/55/609455d21e87430c11fe734abfced50a3bdf177b2f49d41fbb19c199cbc3/uv-0.13.4.tar.gz", hash = "sha256:b0bff5b9a5061f7a35b1d0c1a94c19af134222c48eb7aadc42f85a038be1b248", size = 7482486, upload-time = "2026-10-20T15:12:06.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/bd/4349da5356b17a1c0e36c8552c809925f86f6292de9b1f599f01e8e8093d/uv-0.13.4-py3-none-linux_armv6l.whl", hash = "sha256:205a4f93e568fb24f45a2f3834f1c0a8f1adb5f396bf473c71030ed707dce048", size = 18272390, upload-time = "2026-10-20T15:11:02.468Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/0cb77a1ae43959772f8f7873eb1f4061907fbb1694ce55c79b231f639b1d/uv-0.13.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b4bbacea78c9db136cd2ec3147cbfd9ed910b4db5e1877109bd74d0e73bb2eaf", size = 17384113, upload-time = "2026-10-20T15:11:07.172Z" }, + { url = "https://files.pythonhosted.org/packages/26/44/5a8733dd1b2e8d6f9cffd1ff6428a3e11dcc7e146a7657e32cfb8d9fb4a4/uv-0.13.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:95f4eb2b991b53b50ec2b18ab612fca8ba1e7a75a47af0331fb8bcd21da3eb03", size = 14433723, upload-time = "2026-10-20T15:11:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/f8/39/be14f051bf34a1822d634819890a2d0cba3b69101e633fb7b9f54d7b4020/uv-0.13.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:e90ab42825587821096cb0d071e387468da38cfa22818c91f9c0b3c0453048e8", size = 17816443, upload-time = "2026-10-20T15:11:13.674Z" }, + { url = "https://files.pythonhosted.org/packages/97/a0/5df0f8bc6367dd37b98432a7c462e2918554f6db2a71211574852b8f0727/uv-0.13.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:3a9dcb6762c3ba249d8c084315ba03839082af3ece3536cc4164ec735c351d68", size = 17828025, upload-time = "2026-10-20T15:11:16.806Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9c/2fed5357700b7c304b94214979e4efe680c3bc6e337a97eedaa372fe0947/uv-0.13.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ae6ff2b07892379dc767c9064c2b8bbfac88e767edac7ce28e1b0f15d86abb4", size = 17843737, upload-time = "2026-10-20T15:11:20.043Z" }, + { url = "https://files.pythonhosted.org/packages/4c/2e/ee026284f096236dc3e1abed0316f9edab65c0ea176ea0072c064e62478d/uv-0.13.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25cc14ff4fd8335d3be2cc493a621a003fdafcb0fb1c953c905daabe4def5ab8", size = 18576350, upload-time = "2026-10-20T15:11:24.035Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f1/67fbdb649c8c5d0cb38ea74829080479b77c8631cda5d77fc1b28f027ca7/uv-0.13.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77062b02856c74697f48328d8a6583ab07e6da0a993e86c2db46f3d1da27c637", size = 19831234, upload-time = "2026-10-20T15:11:27.627Z" }, + { url = "https://files.pythonhosted.org/packages/bd/00/7d49e3a1a3e98e5244fa38e0c964dc8de568bf3bb101257a63dc2602efed/uv-0.13.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb0e2028d9a8929884344afb7d91d0f65d9783f640d28aede89fca3602bedde9", size = 19702886, upload-time = "2026-10-20T15:11:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/4b/a1/de02c0913726728eca56ee258875cbba9c7b0572c63f494fd9f55c7852e3/uv-0.13.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e4332791b4d55b6dde8695b7fa6079b26991519f44760887c5dfbd5ca4fe53", size = 17181168, upload-time = "2026-10-20T15:11:34.583Z" }, + { url = "https://files.pythonhosted.org/packages/a8/cd/f4a3c7377674366798c56aabd0f9a1f05687c3939f5ba857a3ea6093ff84/uv-0.13.4-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7b3cdf868e5415631fe797b648c0d6945d38d388f23367bdd0b6332e80a1fcb0", size = 16502020, upload-time = "2026-10-20T15:11:37.88Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f4/ce79657c5a0f51b602db9a663529baafff03b9fe8cc41e09ad3f7246b88a/uv-0.13.4-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:4e6b08578c920b86910897f36bb6da7229c8e7e0187976570e2a538cb28b777e", size = 18000980, upload-time = "2026-10-20T15:11:41.59Z" }, + { url = "https://files.pythonhosted.org/packages/21/e6/7d77022d5661f8e01578bc5423bf02af408220e7e7ac5ee15eb94742c7cb/uv-0.13.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:d86a5dec8ab30c70519c71ca5085c8aaf28664836cbc600951cedaa3fc678cbf", size = 18179083, upload-time = "2026-10-20T15:11:45.191Z" }, + { url = "https://files.pythonhosted.org/packages/f4/40/1bf0324800d38009774ba087a6fbffddc76a3e5bf42c081b9298b1236fb5/uv-0.13.4-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5d89d1028c2e22977d9215cbb79cfe12559cb0c8a507a12e2f3a7e47930cf1bf", size = 18010389, upload-time = "2026-10-20T15:11:48.963Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ec/f352ca2cc3b4b6191bb4ec8cdf4bc190eed0ba8bda4c33b7fd66c5d33cec/uv-0.13.4-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:52b5c753a7c2d5f8323a70bb4c93118988356331d0758afa6446c81f974e7196", size = 19004998, upload-time = "2026-10-20T15:11:52.628Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4f/fc05ff4292edfe785b47874ec86d3d83ca2bf735cff8a9d2170ffb66ad83/uv-0.13.4-py3-none-win32.whl", hash = "sha256:d333f01852b817ba05612de31474739da1af7e5463d119b30a9c4331eba1f408", size = 16190502, upload-time = "2026-10-20T15:11:56.657Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b9/b526eab6c72eacc705a58378f6850fde046b28c86fed01bd42da61367c6b/uv-0.13.4-py3-none-win_amd64.whl", hash = "sha256:b2ff80397273fff0e02c20eacae6882834c811827d6fc08f658db156fe754386", size = 15331833, upload-time = "2026-10-20T15:11:59.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f7/4d5fa89d3d10ff6a84e547ef6e02c45b2f2d50e66682da778acf60db63f1/uv-0.13.4-py3-none-win_arm64.whl", hash = "sha256:deffa5a4afdb48f3e44fb26e80377d256b330ddcad0373daff4b54f6162b43a4", size = 15690151, upload-time = "2026-10-20T15:12:02.74Z" }, ] [[package]] diff --git a/examples/example-ai-crewai/uv.toml b/examples/example-ai-crewai/uv.toml index dc82adcd0..82d6114c4 100644 --- a/examples/example-ai-crewai/uv.toml +++ b/examples/example-ai-crewai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 and uv 0.13.4 drop the compromised eMudhra root and are newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day", uv = "1 day" } diff --git a/examples/example-ai-dedalus/uv.lock b/examples/example-ai-dedalus/uv.lock index e0c9775f6..87710ad73 100644 --- a/examples/example-ai-dedalus/uv.lock +++ b/examples/example-ai-dedalus/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-dedalus/uv.toml b/examples/example-ai-dedalus/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-dedalus/uv.toml +++ b/examples/example-ai-dedalus/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-deepseek/uv.lock b/examples/example-ai-deepseek/uv.lock index c17c4abe2..bd66d5ec4 100644 --- a/examples/example-ai-deepseek/uv.lock +++ b/examples/example-ai-deepseek/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-deepseek/uv.toml b/examples/example-ai-deepseek/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-deepseek/uv.toml +++ b/examples/example-ai-deepseek/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-dspy/uv.lock b/examples/example-ai-dspy/uv.lock index a3eefa6a3..c58b36703 100644 --- a/examples/example-ai-dspy/uv.lock +++ b/examples/example-ai-dspy/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.11'", @@ -10,6 +10,9 @@ resolution-markers = [ exclude-newer = "2026-10-03T03:16:08.499203Z" exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -299,11 +302,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] diff --git a/examples/example-ai-dspy/uv.toml b/examples/example-ai-dspy/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-dspy/uv.toml +++ b/examples/example-ai-dspy/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-fireworks-ai/uv.lock b/examples/example-ai-fireworks-ai/uv.lock index 03c02c70d..978ae3f32 100644 --- a/examples/example-ai-fireworks-ai/uv.lock +++ b/examples/example-ai-fireworks-ai/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-fireworks-ai/uv.toml b/examples/example-ai-fireworks-ai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-fireworks-ai/uv.toml +++ b/examples/example-ai-fireworks-ai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-gemini/uv.lock b/examples/example-ai-gemini/uv.lock index 0f23558c5..f512aff3c 100644 --- a/examples/example-ai-gemini/uv.lock +++ b/examples/example-ai-gemini/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -576,7 +579,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -595,12 +598,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -622,6 +629,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-gemini/uv.toml b/examples/example-ai-gemini/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-gemini/uv.toml +++ b/examples/example-ai-gemini/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-groq/uv.lock b/examples/example-ai-groq/uv.lock index 9c07e662d..3a4b5205b 100644 --- a/examples/example-ai-groq/uv.lock +++ b/examples/example-ai-groq/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-groq/uv.toml b/examples/example-ai-groq/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-groq/uv.toml +++ b/examples/example-ai-groq/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-helicone/uv.lock b/examples/example-ai-helicone/uv.lock index 64778b2f4..28b21350c 100644 --- a/examples/example-ai-helicone/uv.lock +++ b/examples/example-ai-helicone/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-helicone/uv.toml b/examples/example-ai-helicone/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-helicone/uv.toml +++ b/examples/example-ai-helicone/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-hugging-face/uv.lock b/examples/example-ai-hugging-face/uv.lock index 1064d1af9..c911563ad 100644 --- a/examples/example-ai-hugging-face/uv.lock +++ b/examples/example-ai-hugging-face/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-hugging-face/uv.toml b/examples/example-ai-hugging-face/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-hugging-face/uv.toml +++ b/examples/example-ai-hugging-face/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-instructor/uv.lock b/examples/example-ai-instructor/uv.lock index 21bc1548d..6a6d1eace 100644 --- a/examples/example-ai-instructor/uv.lock +++ b/examples/example-ai-instructor/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -268,11 +271,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -1214,7 +1217,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -1233,12 +1236,14 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -1262,6 +1267,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-instructor/uv.toml b/examples/example-ai-instructor/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-instructor/uv.toml +++ b/examples/example-ai-instructor/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-langchain/uv.lock b/examples/example-ai-langchain/uv.lock index d8a1b4c62..d72389757 100644 --- a/examples/example-ai-langchain/uv.lock +++ b/examples/example-ai-langchain/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -827,7 +830,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.63.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -846,12 +849,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -873,6 +880,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-langchain/uv.toml b/examples/example-ai-langchain/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-langchain/uv.toml +++ b/examples/example-ai-langchain/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-langgraph/uv.lock b/examples/example-ai-langgraph/uv.lock index 1dfeabedd..0fc330260 100644 --- a/examples/example-ai-langgraph/uv.lock +++ b/examples/example-ai-langgraph/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.11'", @@ -10,6 +10,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -44,11 +47,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -813,7 +816,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.63.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -832,12 +835,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -859,6 +866,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-langgraph/uv.toml b/examples/example-ai-langgraph/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-langgraph/uv.toml +++ b/examples/example-ai-langgraph/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-litellm/uv.lock b/examples/example-ai-litellm/uv.lock index bfa9da428..d48afee22 100644 --- a/examples/example-ai-litellm/uv.lock +++ b/examples/example-ai-litellm/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "2026-10-03T03:16:09.116916Z" exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -259,11 +262,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] diff --git a/examples/example-ai-litellm/uv.toml b/examples/example-ai-litellm/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-litellm/uv.toml +++ b/examples/example-ai-litellm/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-llamaindex/uv.lock b/examples/example-ai-llamaindex/uv.lock index 1a36872ad..f74f56fb4 100644 --- a/examples/example-ai-llamaindex/uv.lock +++ b/examples/example-ai-llamaindex/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.11'", @@ -10,6 +10,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -290,11 +293,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -1805,7 +1808,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -1824,12 +1827,14 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -1853,6 +1858,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-llamaindex/uv.toml b/examples/example-ai-llamaindex/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-llamaindex/uv.toml +++ b/examples/example-ai-llamaindex/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-mirascope/uv.lock b/examples/example-ai-mirascope/uv.lock index cd488af90..236ddaeb6 100644 --- a/examples/example-ai-mirascope/uv.lock +++ b/examples/example-ai-mirascope/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -536,7 +539,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -555,12 +558,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -582,6 +589,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-mirascope/uv.toml b/examples/example-ai-mirascope/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-mirascope/uv.toml +++ b/examples/example-ai-mirascope/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-mistral/uv.lock b/examples/example-ai-mistral/uv.lock index c7e00ba96..3ae20625e 100644 --- a/examples/example-ai-mistral/uv.lock +++ b/examples/example-ai-mistral/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-mistral/uv.toml b/examples/example-ai-mistral/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-mistral/uv.toml +++ b/examples/example-ai-mistral/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-ollama/uv.lock b/examples/example-ai-ollama/uv.lock index 9084565ed..88ab43899 100644 --- a/examples/example-ai-ollama/uv.lock +++ b/examples/example-ai-ollama/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-ollama/uv.toml b/examples/example-ai-ollama/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-ollama/uv.toml +++ b/examples/example-ai-ollama/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-openai-agents/uv.lock b/examples/example-ai-openai-agents/uv.lock index a2666834f..b86553eac 100644 --- a/examples/example-ai-openai-agents/uv.lock +++ b/examples/example-ai-openai-agents/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -12,6 +12,9 @@ resolution-markers = [ exclude-newer = "2026-10-03T03:16:09.242998Z" exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -46,11 +49,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] diff --git a/examples/example-ai-openai-agents/uv.toml b/examples/example-ai-openai-agents/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-openai-agents/uv.toml +++ b/examples/example-ai-openai-agents/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-openai/uv.lock b/examples/example-ai-openai/uv.lock index a4e0c10e1..abd252aa1 100644 --- a/examples/example-ai-openai/uv.lock +++ b/examples/example-ai-openai/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-openai/uv.toml b/examples/example-ai-openai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-openai/uv.toml +++ b/examples/example-ai-openai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-openrouter/uv.lock b/examples/example-ai-openrouter/uv.lock index d48c3c205..2468a06ab 100644 --- a/examples/example-ai-openrouter/uv.lock +++ b/examples/example-ai-openrouter/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-openrouter/uv.toml b/examples/example-ai-openrouter/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-openrouter/uv.toml +++ b/examples/example-ai-openrouter/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-perplexity/uv.lock b/examples/example-ai-perplexity/uv.lock index 6391fc43a..45e91258d 100644 --- a/examples/example-ai-perplexity/uv.lock +++ b/examples/example-ai-perplexity/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-perplexity/uv.toml b/examples/example-ai-perplexity/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-perplexity/uv.toml +++ b/examples/example-ai-perplexity/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-portkey/uv.lock b/examples/example-ai-portkey/uv.lock index fa1e8f543..77d4a6595 100644 --- a/examples/example-ai-portkey/uv.lock +++ b/examples/example-ai-portkey/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -49,11 +52,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -541,7 +544,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -560,12 +563,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -587,6 +594,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-portkey/uv.toml b/examples/example-ai-portkey/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-portkey/uv.toml +++ b/examples/example-ai-portkey/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-pydantic-ai/uv.lock b/examples/example-ai-pydantic-ai/uv.lock index cac931f92..6679c95fd 100644 --- a/examples/example-ai-pydantic-ai/uv.lock +++ b/examples/example-ai-pydantic-ai/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -13,6 +13,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "ag-ui-protocol" version = "0.1.14" @@ -424,11 +427,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -2108,7 +2111,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -2127,12 +2130,14 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -2156,6 +2161,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-pydantic-ai/uv.toml b/examples/example-ai-pydantic-ai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-pydantic-ai/uv.toml +++ b/examples/example-ai-pydantic-ai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-semantic-kernel/uv.lock b/examples/example-ai-semantic-kernel/uv.lock index 5f8f0ffc8..293cbf9d4 100644 --- a/examples/example-ai-semantic-kernel/uv.lock +++ b/examples/example-ai-semantic-kernel/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'", @@ -14,6 +14,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "aiohappyeyeballs" version = "2.6.1" @@ -429,11 +432,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -2011,7 +2014,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.73.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -2030,12 +2033,14 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -2059,6 +2064,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-semantic-kernel/uv.toml b/examples/example-ai-semantic-kernel/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-semantic-kernel/uv.toml +++ b/examples/example-ai-semantic-kernel/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-smolagents/uv.lock b/examples/example-ai-smolagents/uv.lock index df944934a..7cbaabb7a 100644 --- a/examples/example-ai-smolagents/uv.lock +++ b/examples/example-ai-smolagents/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -792,7 +795,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.63.0" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -811,12 +814,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -838,6 +845,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-smolagents/uv.toml b/examples/example-ai-smolagents/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-smolagents/uv.toml +++ b/examples/example-ai-smolagents/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-together-ai/uv.lock b/examples/example-ai-together-ai/uv.lock index 9dab19c00..eb2c37bd1 100644 --- a/examples/example-ai-together-ai/uv.lock +++ b/examples/example-ai-together-ai/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-together-ai/uv.toml b/examples/example-ai-together-ai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-together-ai/uv.toml +++ b/examples/example-ai-together-ai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-vercel-ai-gateway/uv.lock b/examples/example-ai-vercel-ai-gateway/uv.lock index 641c68ba7..ef3264472 100644 --- a/examples/example-ai-vercel-ai-gateway/uv.lock +++ b/examples/example-ai-vercel-ai-gateway/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-vercel-ai-gateway/uv.toml b/examples/example-ai-vercel-ai-gateway/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-vercel-ai-gateway/uv.toml +++ b/examples/example-ai-vercel-ai-gateway/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/examples/example-ai-xai/uv.lock b/examples/example-ai-xai/uv.lock index 271bc8fce..24f779a26 100644 --- a/examples/example-ai-xai/uv.lock +++ b/examples/example-ai-xai/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-types" version = "0.7.0" @@ -40,11 +43,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.2.25" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -509,7 +512,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { directory = "../../" } dependencies = [ { name = "backoff" }, @@ -528,12 +531,16 @@ otel = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -555,6 +562,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/examples/example-ai-xai/uv.toml b/examples/example-ai-xai/uv.toml index dc82adcd0..e4a5d8a9d 100644 --- a/examples/example-ai-xai/uv.toml +++ b/examples/example-ai-xai/uv.toml @@ -1 +1,3 @@ exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } diff --git a/integration_tests/django5/pyproject.toml b/integration_tests/django5/pyproject.toml index 139cc0457..fe592ad2e 100644 --- a/integration_tests/django5/pyproject.toml +++ b/integration_tests/django5/pyproject.toml @@ -15,6 +15,8 @@ dependencies = [ [tool.uv] required-version = ">=0.5" exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } [tool.uv.sources] posthog = { path = "../..", editable = true } diff --git a/integration_tests/django5/uv.lock b/integration_tests/django5/uv.lock index 68d85d4a7..8f39eb073 100644 --- a/integration_tests/django5/uv.lock +++ b/integration_tests/django5/uv.lock @@ -1,11 +1,14 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.12" [options] exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "anyio" version = "4.14.2" @@ -39,11 +42,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.10.5" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -251,7 +254,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.66.0" +version = "7.75.4" source = { editable = "../../" } dependencies = [ { name = "backoff" }, @@ -264,12 +267,14 @@ dependencies = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, @@ -293,6 +298,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/playgrounds/fastapi-async-client/pyproject.toml b/playgrounds/fastapi-async-client/pyproject.toml index 25cebf297..6476cef65 100644 --- a/playgrounds/fastapi-async-client/pyproject.toml +++ b/playgrounds/fastapi-async-client/pyproject.toml @@ -10,6 +10,8 @@ dependencies = [ [tool.uv] exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } [tool.uv.sources] posthog = { path = "../..", editable = true } diff --git a/playgrounds/fastapi-async-client/uv.lock b/playgrounds/fastapi-async-client/uv.lock index b4852cd30..3548a8c74 100644 --- a/playgrounds/fastapi-async-client/uv.lock +++ b/playgrounds/fastapi-async-client/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.11'", @@ -10,6 +10,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [[package]] name = "annotated-doc" version = "0.0.5" @@ -53,11 +56,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.7.22" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] @@ -396,7 +399,7 @@ wheels = [ [[package]] name = "posthog" -version = "7.61.1" +version = "7.75.4" source = { editable = "../../" } dependencies = [ { name = "backoff" }, @@ -414,12 +417,16 @@ async = [ requires-dist = [ { name = "anthropic", marker = "extra == 'test'", specifier = ">=0.72" }, { name = "backoff", specifier = ">=1.10.0" }, + { name = "celery", marker = "extra == 'test'", specifier = ">=5.3,<6" }, { name = "claude-agent-sdk", marker = "extra == 'test'" }, { name = "coverage", marker = "extra == 'test'" }, { name = "distro", specifier = ">=1.5.0" }, { name = "django", marker = "extra == 'test'", specifier = ">=5.2.15,<6.0" }, { name = "django-stubs", marker = "extra == 'dev'" }, + { name = "djangorestframework", marker = "extra == 'test'", specifier = ">=3.15,<4" }, + { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115,<1" }, { name = "fastmcp", marker = "extra == 'test'", specifier = ">=2.0" }, + { name = "flask", marker = "extra == 'test'", specifier = ">=2.2" }, { name = "freezegun", marker = "extra == 'test'", specifier = "==1.5.1" }, { name = "gevent", marker = "implementation_name == 'cpython' and extra == 'test'", specifier = ">=25.4.1" }, { name = "google-genai", marker = "extra == 'test'" }, @@ -441,6 +448,7 @@ requires-dist = [ { name = "openai-agents", marker = "extra == 'test'", specifier = ">=0.18" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'test'", specifier = ">=1.20.0" }, + { name = "opentelemetry-instrumentation-celery", marker = "extra == 'test'", specifier = ">=0.41b0" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.20.0" }, { name = "opentelemetry-sdk", marker = "extra == 'test'", specifier = ">=1.20.0" }, { name = "packaging", marker = "extra == 'dev'" }, diff --git a/pyproject.toml b/pyproject.toml index fdb74b179..3d1118a74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,6 +131,8 @@ packages = [ [tool.uv] exclude-newer = "7 days" +# certifi 2026.10.19 drops the compromised eMudhra root and is newer than the 7-day cooldown. +exclude-newer-package = { certifi = "1 day" } required-version = ">=0.8.0" # Declares a uv workspace so tooling (incl. Sampo's release flow) discovers the diff --git a/uv.lock b/uv.lock index 7b8aa80bd..5b6e2994f 100644 --- a/uv.lock +++ b/uv.lock @@ -15,6 +15,9 @@ resolution-markers = [ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for backwards compatibility when using relative exclude-newer values. exclude-newer-span = "P7D" +[options.exclude-newer-package] +certifi = { timestamp = "0001-01-01T00:00:00Z", span = "P1D" } + [manifest] members = [ "openfeature-provider-posthog", @@ -488,11 +491,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.6.15" +version = "2026.10.19" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, + { url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" }, ] [[package]] From 1b385d404202de8f17fa565d558b89814c590fc7 Mon Sep 17 00:00:00 2001 From: Eli Reisman Date: Fri, 23 Oct 2026 10:01:34 -0700 Subject: [PATCH 70/70] test: send NaN and Infinity as null on the v1 path, as #1081 does on main #1081 keeps an event whose properties hold a non-finite float and writes the value as null. The v1 before_send test expected that event to be dropped; a capture v1 body test now pins the null on the wire, and the migration guide says so. Co-Authored-By: Claude Opus 5.5 --- docs/migration-7.x-to-8.0.md | 5 +++-- posthog/test/test_before_send.py | 2 -- posthog/test/test_capture_send.py | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/migration-7.x-to-8.0.md b/docs/migration-7.x-to-8.0.md index 87abcce7e..e4d287a10 100644 --- a/docs/migration-7.x-to-8.0.md +++ b/docs/migration-7.x-to-8.0.md @@ -113,8 +113,9 @@ Capture rejects a whole batch when one event cannot be parsed. - An event whose name is missing, `None`, empty or not a string is dropped. The SDK logs one warning per reason per process. 7.x sent it. - An event whose `before_send` hook sets `distinct_id` to `None` or a non-string is dropped, with one warning per reason per process. The SDK does not convert the hook's value or make up an ID. 7.x sent it, and capture would reject the whole batch. - PostHog drops an event whose name is over 200 UTF-8 bytes (`event_name_too_long`), and `on_error` reports it. 7.x sent events to legacy capture, which had no event name limit. -- An event that cannot be serialized to JSON is dropped and logged, for example one with `NaN` or `Infinity` in its properties. 7.x sent `NaN` as invalid JSON. -- A property or option key that JSON cannot represent, such as a tuple, is dropped without a log, and the rest of the event is sent. 7.x dropped the event. `int`, finite `float`, `bool` and `None` keys are still converted to strings. A `NaN` or infinite `float` key drops the event, as a `NaN` value does. +- A `NaN` or infinite `float` value is sent as `null`, as in 7.75 and later, and the event is kept. Earlier 7.x versions sent invalid JSON, which made capture reject the whole batch. +- An event that cannot be serialized to JSON, for example one with a circular reference, is dropped and logged. +- A property or option key that JSON cannot represent, such as a tuple, is dropped without a log, and the rest of the event is sent. 7.x dropped the event. `int`, finite `float`, `bool` and `None` keys are still converted to strings. A `NaN` or infinite `float` key still drops the event. ## Event uuids diff --git a/posthog/test/test_before_send.py b/posthog/test/test_before_send.py index af0dac383..acdddb87d 100644 --- a/posthog/test/test_before_send.py +++ b/posthog/test/test_before_send.py @@ -254,8 +254,6 @@ def test_before_send_callback_non_dict_output_drops_event(self): "private-value", ["malformed", "valid"], ), - # A value json cannot write costs only that event, never the batch. - ("non_finite_value", "private-key", float("nan"), ["valid"]), ] ) def test_malformed_before_send_event_does_not_stop_consumer_or_shutdown( diff --git a/posthog/test/test_capture_send.py b/posthog/test/test_capture_send.py index 2a951e8d1..d3b7b17ab 100644 --- a/posthog/test/test_capture_send.py +++ b/posthog/test/test_capture_send.py @@ -180,6 +180,27 @@ def test_custom_sdk_info_headers(self) -> None: self.assertEqual(headers[_HEADER_SDK_INFO], "posthog-python/9.9.9") self.assertEqual(headers["User-Agent"], "posthog-python/9.9.9") + def test_non_finite_floats_are_sent_as_null(self) -> None: + session = _RecordingSession(_results_response({})) + event = _msg( + "u-1", properties={"score": float("inf"), "nested": [float("nan"), 1.5]} + ) + _post_v1( + "phc_key", + "https://app.posthog.com/", + _build_v1_batch_body([_to_v1_event(event)]), + attempt=1, + request_id="req-123", + session=session, + ) + body = json.loads( + session.calls[0]["data"], + parse_constant=lambda token: (_ for _ in ()).throw(ValueError(token)), + ) + properties = body["batch"][0]["properties"] + self.assertIsNone(properties["score"]) + self.assertEqual(properties["nested"], [None, 1.5]) + def test_no_api_key_in_body(self) -> None: # v1 authenticates via the Bearer header; the key must not leak into the body. data = self._post(_results_response({}))["data"]