Skip to content

SDK-2614: Python - Support configuration for IDV shortened flow - python#454

Open
mehmet-yoti wants to merge 1 commit intomasterfrom
websdk-auto/SDK-2614-python-python---support-configuration-for-idv-shortened-flow
Open

SDK-2614: Python - Support configuration for IDV shortened flow - python#454
mehmet-yoti wants to merge 1 commit intomasterfrom
websdk-auto/SDK-2614-python-python---support-configuration-for-idv-shortened-flow

Conversation

@mehmet-yoti
Copy link
Copy Markdown
Contributor

Summary

Adds support for the IDV shortened flow in the Python SDK by introducing configurable suppressed_screens on SdkConfig, plus new builders for a WATCHLIST_ADVANCED_CA check and a FACE_CAPTURE task, along with the matching response types for retrieval. This brings the Python SDK in line with other Yoti SDKs for SDK-2614.

Changes

  • yoti_python_sdk/doc_scan/constants.py: Adds WATCHLIST_ADVANCED_CA_CHECK_TYPE, FACE_CAPTURE, and suppressable screen identifiers (ID_DOCUMENT_EDUCATION, ID_DOCUMENT_REQUIREMENTS, SUPPLEMENTARY_DOCUMENT_EDUCATION, ZOOM_LIVENESS_EDUCATION, STATIC_LIVENESS_EDUCATION, FACE_CAPTURE_EDUCATION, FLOW_COMPLETION).
  • session/create/sdk_config.py: Adds suppressed_screens field, with_suppressed_screens(...) builder method, property accessor, and JSON serialisation (omitted when unset via remove_null_values).
  • session/create/check/watchlist_advanced_ca.py (new): WatchlistAdvancedCaProfilesCheck, WatchlistAdvancedCaProfilesCheckConfig, WatchlistAdvancedCaSourcesConfig, and WatchlistAdvancedCaProfilesCheckBuilder with with_remove_deceased, with_share_url, with_sources.
  • session/create/task/face_capture.py (new): RequestedFaceCaptureTask, RequestedFaceCaptureTaskConfig, RequestedFaceCaptureTaskBuilder (empty config, serialises to {}).
  • session/retrieve/check_response.py + get_session_result.py: Adds WatchlistAdvancedCaProfilesCheckResponse, wires it into the type map, and exposes watchlist_screening_checks and watchlist_advanced_ca_checks filtered accessors.
  • session/retrieve/task_response.py + resource_response.py: Adds FaceCaptureTaskResponse and registers it against the FACE_CAPTURE task type.
  • doc_scan/__init__.py and the create check / task package __init__s: Re-export the new builders (WatchlistScreeningCheckBuilder, WatchlistAdvancedCaProfilesCheckBuilder, WatchlistAdvancedCaSourcesConfig, RequestedFaceCaptureTaskBuilder).
  • tests/doc_scan/session/create/test_sdk_config.py: Adds coverage for setting/omitting/empty suppressed_screens and its JSON serialisation behaviour.

QA Test Steps

  1. Install the branch locally: pip install -e . from the repo root.
  2. Run the existing test suite to catch regressions: pytest yoti_python_sdk/tests/doc_scan -q.
  3. Run the new SDK config tests specifically: pytest yoti_python_sdk/tests/doc_scan/session/create/test_sdk_config.py -q and confirm test_should_build_correctly, test_not_passing_suppressed_screens, test_passing_empty_suppressed_screens, test_suppressed_screens_serializes_to_json, and test_unset_suppressed_screens_not_in_json all pass.
  4. Happy path — suppressed screens serialisation. In a Python shell:
    from yoti_python_sdk.doc_scan import SdkConfigBuilder, constants
    import json
    cfg = (SdkConfigBuilder()
           .with_allows_camera()
           .with_suppressed_screens([
               constants.ID_DOCUMENT_EDUCATION,
               constants.FLOW_COMPLETION,
           ])
           .build())
    print(json.dumps(cfg.to_json()))
    Verify the JSON contains "suppressed_screens": ["ID_DOCUMENT_EDUCATION", "FLOW_COMPLETION"].
  5. Edge case — omitted field is not serialised. Build an SdkConfig without calling with_suppressed_screens(...) and confirm the key is absent from to_json() output.
  6. Edge case — empty list is preserved. Call with_suppressed_screens([]) and confirm to_json()["suppressed_screens"] == [] (empty list survives remove_null_values).
  7. Face Capture task builder. Run:
    from yoti_python_sdk.doc_scan import RequestedFaceCaptureTaskBuilder
    t = RequestedFaceCaptureTaskBuilder.build()
    assert t.type == "FACE_CAPTURE"
    assert t.config.to_json() == {}
  8. Watchlist Advanced CA check builder. Run:
    from yoti_python_sdk.doc_scan import (
        WatchlistAdvancedCaProfilesCheckBuilder,
        WatchlistAdvancedCaSourcesConfig,
    )
    chk = (WatchlistAdvancedCaProfilesCheckBuilder()
           .with_remove_deceased(True)
           .with_share_url(False)
           .with_sources(WatchlistAdvancedCaSourcesConfig(types=["pep", "sanction"]))
           .build())
    assert chk.type == "WATCHLIST_ADVANCED_CA"
    print(chk.config.to_json())
    Verify the config JSON includes remove_deceased, share_url, and a sources object with types: ["pep", "sanction"]; unset fields should be omitted.
  9. Session result parsing — new check type. Feed a mock session JSON containing a check with "type": "WATCHLIST_ADVANCED_CA" into GetSessionResult (see get_session_result.py:82-86) and assert:
    • result.watchlist_advanced_ca_checks returns the check;
    • result.watchlist_screening_checks is unaffected for a WATCHLIST_SCREENING check.
  10. Session result parsing — new task type. Feed a mock resource JSON with a task of "type": "FACE_CAPTURE" through ResourceResponse (see resource_response.py:36-41) and confirm the task is instantiated as FaceCaptureTaskResponse.
  11. End-to-end IDV session (integration, if sandbox credentials are available): create a session using SessionSpecBuilder with SdkConfigBuilder().with_suppressed_screens([...]), a RequestedFaceCaptureTaskBuilder.build() task, and a WatchlistAdvancedCaProfilesCheckBuilder check. Confirm the Yoti API accepts the request and the IDV web flow skips the suppressed screens.
  12. Regression — verify existing builders (RequestedLivenessCheckBuilder, RequestedFaceMatchCheckBuilder, WatchlistScreeningCheckBuilder, RequestedTextExtractionTaskBuilder, NotificationConfigBuilder) still import from yoti_python_sdk.doc_scan without errors.

Notes

  • suppressed_screens is passed through to the API as-is; the SDK does not validate the screen identifiers beyond exposing the constants defined in constants.py — unknown values will be forwarded to the backend.
  • WatchlistAdvancedCaSourcesConfig.types defaults to [] when None is supplied, and always serialises the types key (even when empty). Confirm this matches the backend contract if strict omission is expected.
  • RequestedFaceCaptureTaskConfig currently has no configurable fields and serialises to {}; extend it when the API adds options (e.g. manual capture toggles).
  • No changes to authentication, request signing, or transport; the risk surface is limited to payload construction and response parsing.
  • Follow-ups: consider adding unit tests for WatchlistAdvancedCaProfilesCheckBuilder, RequestedFaceCaptureTaskBuilder, and the new retrieval response classes — this PR only extends the existing test_sdk_config.py.

Related Jira: SDK-2614
Auto-generated by n8n + Claude CLI

@sonarqubecloud
Copy link
Copy Markdown

@mehmet-yoti
Copy link
Copy Markdown
Contributor Author

🤖 Claude Code Review

Code Review Findings

Summary

This branch adds three feature-aligned capabilities for the IDV shortened-flow:

  1. A new suppressed_screens option on SdkConfig.
  2. A new WatchlistAdvancedCaProfilesCheck(Builder|Config) plus a WatchlistAdvancedCaSourcesConfig, with matching WatchlistAdvancedCaProfilesCheckResponse retrieval type.
  3. A new RequestedFaceCaptureTask(Builder|Config) plus matching FaceCaptureTaskResponse.

The code cleanly follows the existing builder/serializer idioms in the SDK, but there are several correctness, API design, and test-coverage gaps worth addressing before merging.


Critical

None.


Major

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py:77 — Silent coercion of None to [] in WatchlistAdvancedCaSourcesConfig.
    The constructor does self.__types = types or []. This means callers that explicitly pass types=None (or forget to set it) will emit {"types": []} in the payload because remove_null_values will not strip an empty list. If the backend distinguishes between "omit sources.types" and "sources.types = empty list", this may unintentionally override server-side defaults.
    Suggested fix: keep types as None when not supplied, and let to_json/remove_null_values drop it:

    def __init__(self, types=None):
        self.__types = types
  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py — No unit tests for the new builder, config, or JSON shape.
    Every other check builder in this package has a dedicated test file. Without tests we cannot pin: (a) the wire payload (type/config.sources.types/remove_deceased/share_url), (b) default/omitted behavior, (c) JSON encoding through YotiEncoder.
    Suggested fix: add yoti_python_sdk/tests/doc_scan/session/create/check/test_watchlist_advanced_ca_check.py mirroring test_wathclist_check.py, including a case that builds with WatchlistAdvancedCaSourcesConfig(["type_a", "type_b"]) and asserts the serialized payload.

  • yoti_python_sdk/doc_scan/session/create/task/face_capture.py — No unit tests for RequestedFaceCaptureTaskBuilder.
    Other task builders have paired tests (e.g. test_text_extraction_task.py). This one is small but should still confirm that to_json() produces {"type": "FACE_CAPTURE", "config": {}}.
    Suggested fix: add a short test_face_capture_task.py asserting type, class hierarchy, and JSON shape.

  • yoti_python_sdk/doc_scan/session/create/task/face_capture.py:39-47RequestedFaceCaptureTaskBuilder.build is a @staticmethod, inconsistent with the rest of the SDK.
    Every sibling builder uses an instance __init__ + instance build(self). A staticmethod build() means it can also be called as RequestedFaceCaptureTaskBuilder.build() (no instantiation), which is different from how every other builder in the codebase is used. If configuration knobs are added later, changing to an instance method is a backwards-incompatible change.
    Suggested fix:

    class RequestedFaceCaptureTaskBuilder(object):
        def build(self):
            return RequestedFaceCaptureTask(RequestedFaceCaptureTaskConfig())
  • yoti_python_sdk/doc_scan/__init__.py:10-13 vs yoti_python_sdk/doc_scan/session/create/check/__init__.py:6WatchlistAdvancedCaSourcesConfig is exported from the top-level doc_scan package but not from doc_scan.session.create.check.
    This is inconsistent with the rest of the package (check builders are exported from both locations) and forces users who import from the sub-package to reach into watchlist_advanced_ca directly.
    Suggested fix: add WatchlistAdvancedCaSourcesConfig to the from .watchlist_advanced_ca import ... line and to __all__ in yoti_python_sdk/doc_scan/session/create/check/__init__.py.


Minor

  • yoti_python_sdk/doc_scan/constants.py:46-52 — Seven new screen-name constants are introduced but the only enforcement of "valid values" is at the server.
    Callers pass raw strings via with_suppressed_screens([...]) with no validation or discoverability. At minimum, mention the constants by name in the docstring.
    Suggested fix: extend the docstring of SdkConfigBuilder.with_suppressed_screens to reference the *_EDUCATION / *_REQUIREMENTS / FLOW_COMPLETION constants in yoti_python_sdk.doc_scan.constants.

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py:14WatchlistAdvancedCaProfilesCheckBuilder().build() produces a check with a completely empty config ({}).
    If the backend requires at least sources or rejects a fully-empty config, this is a silent footgun.
    Suggested fix: add a precondition in build() raising ValueError if all three fields are None (only if the backend actually rejects empty configs); otherwise add a negative-path test pinning the current behaviour.

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py:57-64to_json passes the WatchlistAdvancedCaSourcesConfig instance directly into remove_null_values.
    This relies on YotiEncoder later serializing the nested instance via its to_json(). Elsewhere to_json() produces a pure-dict tree.
    Suggested fix (optional): "sources": self.__sources.to_json() if self.__sources is not None else None.

  • yoti_python_sdk/doc_scan/session/retrieve/get_session_result.py:236-243watchlist_screening_checks property added even though WatchlistScreeningCheckResponse pre-existed.
    Good cleanup, but arguably out of scope for SDK-2614 (IDV shortened flow). Worth calling out in the PR description.

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.pyto_json uses mixed access styles (self.__remove_deceased vs. self.share_url).
    Sibling files use the property form consistently.
    Suggested fix: use self.remove_deceased, self.share_url, self.sources properties throughout to_json.

  • yoti_python_sdk/tests/doc_scan/session/create/test_sdk_config.py:58 — Uses is for list-identity comparison.
    Identity comparisons on mutable containers are fragile — if the builder ever defensively copies (a good practice), this test will fail for the wrong reason.
    Suggested fix: assert result.suppressed_screens == self.SOME_SUPPRESSED_SCREENS.

  • yoti_python_sdk/doc_scan/session/retrieve/check_response.py:197-202 and task_response.py:184-189 — Empty pass subclasses with no added behavior.
    Consistent with siblings and fine for extensibility, but consider whether WatchlistAdvancedCaProfilesCheckResponse will eventually expose structured fields (e.g., number of hits). If so, file a follow-up ticket.


Nit

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py:114 — Class name WatchlistAdvancedCaProfilesCheckBuilder — consider WatchlistAdvancedCAProfilesCheckBuilder (acronym-uppercase).
    Cross-SDK consistency is the tiebreaker.

  • yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py:14-25 — Docstrings for __init__ say bool or None, builder methods say only bool. Minor consistency issue.

  • yoti_python_sdk/doc_scan/constants.py:44FACE_CAPTURE is now overloaded as both a task type and root of screen constants (FACE_CAPTURE_EDUCATION).
    Fine in practice; consider # --- Suppressible screens --- / # --- Task types --- comment blocks for readability.

  • yoti_python_sdk/doc_scan/__init__.py:10-13 — Only WatchlistAdvancedCaSourcesConfig is re-exported from the nested module, not WatchlistAdvancedCaProfilesCheckConfig.
    Callers rarely instantiate Config objects directly; noting for completeness.

  • yoti_python_sdk/doc_scan/session/create/task/face_capture.py:15to_json returns literal {}.
    Since RequestedTask.to_json wraps this in remove_null_values({"type": ..., "config": {}}), the config: {} entry will be preserved (not null-stripped). Confirm with the backend that an empty-object config is acceptable for FACE_CAPTURE.

  • yoti_python_sdk/doc_scan/session/retrieve/get_session_result.py:85-86 — Whitespace-only cleanup. Noted so reviewers don't chase it as a semantic change.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for the IDV shortened flow in the Python Doc Scan SDK by allowing SDK config to suppress specific client screens, and by introducing new request/response types for a Watchlist Advanced CA check and Face Capture task.

Changes:

  • Add suppressed_screens to SdkConfig (builder + JSON serialization) and screen identifier constants.
  • Add builders for WATCHLIST_ADVANCED_CA (check) and FACE_CAPTURE (task), plus retrieval response types and parsing/type registration.
  • Extend GetSessionResult with filtered accessors for watchlist screening vs. advanced CA checks; add SDK config tests for suppressed screens.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
yoti_python_sdk/doc_scan/constants.py Adds new constants for watchlist advanced CA, face capture, and suppressable screen identifiers.
yoti_python_sdk/doc_scan/session/create/sdk_config.py Adds suppressed_screens to config/builder and serializes it in to_json().
yoti_python_sdk/doc_scan/session/create/check/watchlist_advanced_ca.py New builder/config for Watchlist Advanced CA Profiles check.
yoti_python_sdk/doc_scan/session/create/check/init.py Re-exports the new Watchlist Advanced CA builder.
yoti_python_sdk/doc_scan/session/create/task/face_capture.py New builder/config for Face Capture task (empty config).
yoti_python_sdk/doc_scan/session/create/task/init.py Re-exports the new Face Capture task builder.
yoti_python_sdk/doc_scan/session/retrieve/check_response.py Adds WatchlistAdvancedCaProfilesCheckResponse.
yoti_python_sdk/doc_scan/session/retrieve/get_session_result.py Registers parsing for WATCHLIST_ADVANCED_CA and adds filtered accessors for watchlist checks.
yoti_python_sdk/doc_scan/session/retrieve/task_response.py Adds FaceCaptureTaskResponse.
yoti_python_sdk/doc_scan/session/retrieve/resource_response.py Registers parsing for FACE_CAPTURE tasks.
yoti_python_sdk/doc_scan/init.py Re-exports the new builders/config types at the package level.
yoti_python_sdk/tests/doc_scan/session/create/test_sdk_config.py Adds coverage for setting/omitting/serializing suppressed_screens.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 82 to +253
@@ -230,6 +232,26 @@ def id_document_comparison_checks(self):
"""
return self.__checks_of_type((IDDocumentComparisonCheckResponse,))

@property
def watchlist_screening_checks(self):
"""
A filtered list of checks, returning only Watchlist Screening checks

:return: the Watchlist Screening checks
:rtype: list[WatchlistScreeningCheckResponse]
"""
return self.__checks_of_type((WatchlistScreeningCheckResponse,))

@property
def watchlist_advanced_ca_checks(self):
"""
A filtered list of checks, returning only Watchlist Advanced CA Profiles checks

:return: the Watchlist Advanced CA Profiles checks
:rtype: list[WatchlistAdvancedCaProfilesCheckResponse]
"""
return self.__checks_of_type((WatchlistAdvancedCaProfilesCheckResponse,))
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WATCHLIST_ADVANCED_CA parsing and the new watchlist_screening_checks / watchlist_advanced_ca_checks accessors are not covered by the existing GetSessionResult unit tests. Please extend tests/doc_scan/session/retrieve/test_get_session_result.py to include a WATCHLIST_SCREENING and WATCHLIST_ADVANCED_CA check and assert the new filtered properties return the correct instances.

Copilot uses AI. Check for mistakes.
Comment on lines 36 to 40
types = {
constants.ID_DOCUMENT_TEXT_DATA_EXTRACTION: TextExtractionTaskResponse,
constants.SUPPLEMENTARY_DOCUMENT_TEXT_DATA_EXTRACTION: SupplementaryDocumentTextExtractionTaskResponse,
constants.FACE_CAPTURE: FaceCaptureTaskResponse,
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new FACE_CAPTURE task type mapping isn’t covered by existing ResourceResponse tests. Please update tests/doc_scan/session/retrieve/test_resource_response.py to include a task with type FACE_CAPTURE and assert it is parsed as FaceCaptureTaskResponse (and that unknown types still fall back to TaskResponse).

Copilot uses AI. Check for mistakes.
Comment on lines 54 to +58
assert result.success_url is self.SOME_SUCCESS_URL
assert result.error_url is self.SOME_ERROR_URL
assert result.privacy_policy_url is self.SOME_PRIVACY_POLICY_URL
assert result.allow_handoff is True
assert result.suppressed_screens is self.SOME_SUPPRESSED_SCREENS
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions use is for string/list comparisons (e.g. success_url, error_url, privacy_policy_url, suppressed_screens). is checks object identity and can be flaky (string interning, list copies); use == for value equality and reserve is for None/True/False comparisons.

Copilot uses AI. Check for mistakes.
Comment on lines 45 to +50
:param privacy_policy_url: the privacy policy url
:type privacy_policy_url: str
:param allow_handoff: boolean flag for allow_handoff
:type allow_handoff: bool
:param suppressed_screens: the screens to suppress in the IDV flow
:type suppressed_screens: list[str]
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor docstring lists privacy_policy_url before allow_handoff, but the actual parameter order is allow_handoff then privacy_policy_url. Please align the docstring with the signature (or reorder the arguments) to avoid misleading callers reading the docs.

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +47
class RequestedFaceCaptureTask(RequestedTask):
"""
Requests creation of a Face Capture Task
"""

def __init__(self, config):
"""
:param config: the face capture task configuration
:type config: RequestedFaceCaptureTaskConfig
"""
self.__config = config

@property
def type(self):
return constants.FACE_CAPTURE

@property
def config(self):
return self.__config


class RequestedFaceCaptureTaskBuilder(object):
"""
Builder to assist creation of :class:`RequestedFaceCaptureTask`
"""

@staticmethod
def build():
config = RequestedFaceCaptureTaskConfig()
return RequestedFaceCaptureTask(config)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds a new task builder/config (RequestedFaceCaptureTask*), but there is no corresponding unit test in tests/doc_scan/session/create/task/ (similar tasks like text extraction have coverage). Please add tests covering type, config.to_json(), and serialization via YotiEncoder to prevent regressions.

Copilot uses AI. Check for mistakes.
Comment on lines +9 to +164
class WatchlistAdvancedCaProfilesCheckConfig(YotiSerializable):
"""
The configuration applied when creating a Watchlist Advanced CA Profiles check.
"""

def __init__(self, remove_deceased=None, share_url=None, sources=None):
"""
:param remove_deceased: whether to remove deceased individuals from results
:type remove_deceased: bool or None
:param share_url: whether to share the URL in results
:type share_url: bool or None
:param sources: the sources configuration
:type sources: WatchlistAdvancedCaSourcesConfig or None
"""
self.__remove_deceased = remove_deceased
self.__share_url = share_url
self.__sources = sources

@property
def remove_deceased(self):
"""
Whether deceased individuals are removed from results

:return: remove deceased flag
:rtype: bool or None
"""
return self.__remove_deceased

@property
def share_url(self):
"""
Whether the URL is shared in results

:return: share URL flag
:rtype: bool or None
"""
return self.__share_url

@property
def sources(self):
"""
The sources configuration for the advanced CA profiles check

:return: the sources configuration
:rtype: WatchlistAdvancedCaSourcesConfig or None
"""
return self.__sources

def to_json(self):
return remove_null_values(
{
"remove_deceased": self.__remove_deceased,
"share_url": self.__share_url,
"sources": self.__sources,
}
)


class WatchlistAdvancedCaSourcesConfig(YotiSerializable):
"""
Configures the sources for a Watchlist Advanced CA Profiles check.
"""

def __init__(self, types=None):
"""
:param types: the list of source types to check against
:type types: list[str] or None
"""
self.__types = types or []

@property
def types(self):
"""
The list of source types

:return: the source types
:rtype: list[str]
"""
return self.__types

def to_json(self):
return remove_null_values({"types": self.__types})


class WatchlistAdvancedCaProfilesCheck(RequestedCheck):
"""
Requests creation of a Watchlist Advanced CA Profiles check
"""

def __init__(self, config):
"""
:param config: the Watchlist Advanced CA Profiles check configuration
:type config: WatchlistAdvancedCaProfilesCheckConfig
"""
self.__config = config

@property
def type(self):
return constants.WATCHLIST_ADVANCED_CA_CHECK_TYPE

@property
def config(self):
return self.__config


class WatchlistAdvancedCaProfilesCheckBuilder(object):
"""
Builder to assist creation of :class:`WatchlistAdvancedCaProfilesCheck`
"""

def __init__(self):
self.__remove_deceased = None
self.__share_url = None
self.__sources = None

def with_remove_deceased(self, remove_deceased):
"""
Sets whether deceased individuals should be removed from results

:param remove_deceased: the remove deceased flag
:type remove_deceased: bool
:return: the builder
:rtype: WatchlistAdvancedCaProfilesCheckBuilder
"""
self.__remove_deceased = remove_deceased
return self

def with_share_url(self, share_url):
"""
Sets whether the URL should be shared in results

:param share_url: the share URL flag
:type share_url: bool
:return: the builder
:rtype: WatchlistAdvancedCaProfilesCheckBuilder
"""
self.__share_url = share_url
return self

def with_sources(self, sources):
"""
Sets the sources configuration for the check

:param sources: the sources configuration
:type sources: WatchlistAdvancedCaSourcesConfig
:return: the builder
:rtype: WatchlistAdvancedCaProfilesCheckBuilder
"""
self.__sources = sources
return self

def build(self):
config = WatchlistAdvancedCaProfilesCheckConfig(
self.__remove_deceased, self.__share_url, self.__sources
)
return WatchlistAdvancedCaProfilesCheck(config)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces a new check builder/config (WatchlistAdvancedCaProfilesCheck*), but there are no unit tests alongside existing check builder tests (e.g. in tests/doc_scan/session/create/check/). Please add coverage for builder defaults vs. set fields and the expected to_json() output, including how sources/types serializes.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants