Skip to content

sift_client.pytest_plugin

FUNCTION DESCRIPTION
client_has_connection

Verify the SiftClient can reach Sift via /ping.

module_substep

Create a per-module step when at least one test in the module is gated on.

pytest_addoption

Register Sift-specific command-line options and ini keys.

pytest_configure

Register the Sift gate markers so they show up in pytest --markers.

pytest_runtest_makereport

Capture pytest outcomes so assertion failures and skips land on the Sift step.

report_context

Lazy session-scoped Sift ReportContext.

sift_client

Default SiftClient resolved from environment variables and ini keys.

step

Create an outer step for the function when the Sift gate is on.

ATTRIBUTE DESCRIPTION
REPORT_CONTEXT

TYPE: Any

REPORT_CONTEXT module-attribute

REPORT_CONTEXT: Any = None

client_has_connection

client_has_connection(
    pytestconfig: Config, request: FixtureRequest
) -> bool

Verify the SiftClient can reach Sift via /ping.

Consulted at session start by report_context in online mode. A failed ping raises through report_context and aborts the session with pytest.UsageError. Override this fixture in your conftest to use a different reachability signal (e.g. a cached auth token) for environments where pinging is the wrong check. Returns False in --sift-disabled mode without constructing a client.

module_substep

module_substep(
    request: FixtureRequest, pytestconfig: Config
) -> Generator[NewStep | _NoopStep | None, None, None]

Create a per-module step when at least one test in the module is gated on.

Inspects the module's collected items rather than gating on a single marker, so a module with mixed inclusion/exclusion still produces the module-level step (individual step fixtures then decide per-test). When every test in the module is excluded, the substep is skipped without requesting report_context.

pytest_addoption

pytest_addoption(parser: Parser) -> None

Register Sift-specific command-line options and ini keys.

Each option can be set on the command line or under [tool.pytest.ini_options] in pyproject.toml (or [pytest] in pytest.ini). CLI values take precedence over ini values, which take precedence over the built-in default.

pytest_configure

pytest_configure(config: Config) -> None

Register the Sift gate markers so they show up in pytest --markers.

pytest_runtest_makereport

pytest_runtest_makereport(item: Item, call: CallInfo[Any])

Capture pytest outcomes so assertion failures and skips land on the Sift step.

report_context

report_context(
    request: FixtureRequest, pytestconfig: Config
) -> Generator[
    ReportContext | _NoopReportContext, None, None
]

Lazy session-scoped Sift ReportContext.

The fixture is no longer autouse; it's instantiated on the first call to request.getfixturevalue("report_context"), which today happens inside the gated step and module_substep fixtures. If every test in the session is excluded via the marker gate, this fixture is never resolved and no ReportContext (or teardown subprocess) is created.

What gets yielded depends on the mode:

  • --sift-disabled: a stub context with no client, no network, and no log file. Test code that calls step.measure(...) keeps working because bounds are evaluated locally.
  • --sift-offline: a real ReportContext, but the session-start ping is skipped, all create/update calls go to the JSONL log file, and the import-test-result-log replay subprocess is not spawned at session end.
  • default (online): verify connectivity via client_has_connection before constructing the context. A failed ping aborts the session with pytest.UsageError and points at --sift-offline and --sift-disabled as escape hatches.

The log-file destination is controlled by --sift-log-file; defaults to a temp file when unset.

sift_client

sift_client(pytestconfig: Config) -> SiftClient

Default SiftClient resolved from environment variables and ini keys.

Each credential is read from its environment variable first. The URIs (SIFT_GRPC_URI, SIFT_REST_URI) additionally fall back to the sift_grpc_uri / sift_rest_uri ini keys, since they are stable per-org values that are safe to commit. SIFT_API_KEY is intentionally env-only — use pytest-dotenv (already a project dependency) to load it from a .env file kept out of version control.

Projects that need custom construction (TLS toggles, custom timeouts, etc.) can override this fixture by defining their own sift_client in their conftest.py; pytest fixture resolution prefers the local definition.

In --sift-offline mode the missing-credential check is relaxed: real env vars and ini values still win when set (so the client is constructible against a real backend even though no calls are made), but anything still missing is filled with a placeholder. In --sift-disabled mode the credential resolution is skipped entirely and placeholders are always used.

step

step(
    request: FixtureRequest, pytestconfig: Config
) -> Generator[NewStep | _NoopStep | None, None, None]

Create an outer step for the function when the Sift gate is on.

Resolves the gate via _sift_enabled_for(request.node, ini_default): sift_exclude marker forces off, sift_include forces on, otherwise the sift_autouse ini default applies. When on, requests the session report_context lazily — the first gated test in the session triggers its creation, subsequent gated tests reuse it. In --sift-disabled mode the report context is a stub, so the gate still runs but the resulting step is a no-op shim.