Skip to content

ADT

psengine.entity_lists.entity_list

EntityList

Bases: ListInfoOut

Validate data received from /create endpoint.

created instance-attribute

created: datetime

id_ class-attribute instance-attribute

id_: str = Field(alias='id')

log class-attribute instance-attribute

log: Logger = Field(
    exclude=True, default=getLogger(__name__)
)

match_mgr class-attribute instance-attribute

match_mgr: EntityMatchMgr = Field(exclude=True)

model_config class-attribute instance-attribute

model_config = ConfigDict(arbitrary_types_allowed=True)

name instance-attribute

name: str

organisation_id class-attribute instance-attribute

organisation_id: str | None = None

organisation_name class-attribute instance-attribute

organisation_name: str | None = None

owner_id instance-attribute

owner_id: str

owner_name instance-attribute

owner_name: str

owner_organisation_details class-attribute instance-attribute

owner_organisation_details: OwnerOrganisationDetails = (
    Field(default_factory=OwnerOrganisationDetails)
)

rf_client class-attribute instance-attribute

rf_client: RFClient = Field(exclude=True)

type_ class-attribute instance-attribute

type_: str = Field(alias='type')

updated instance-attribute

updated: datetime

__eq__

__eq__(other: EntityList)
Source code in psengine/entity_lists/entity_list.py
def __eq__(self, other: 'EntityList'):
    return self.id_ == other.id_

__hash__

__hash__()
Source code in psengine/entity_lists/entity_list.py
def __hash__(self):
    return hash(self.id_)

__str__

__str__() -> str

Return the string representation of the list.

RETURNS DESCRIPTION
str

List data with standard info and entities.

Source code in psengine/entity_lists/entity_list.py
def __str__(self) -> Annotated[str, Doc('List data with standard info and entities.')]:
    """Return the string representation of the list."""

    def format_date(date):
        return date.strftime(TIMESTAMP_STR)

    def format_field(name, value):
        return f'{name}: {value or "None"}'

    main_fields = [
        format_field('id', self.id_),
        format_field('name', self.name),
        format_field('type', self.type_),
        format_field('created', format_date(self.created)),
        format_field('last updated', format_date(self.updated)),
        format_field('owner id', self.owner_id),
        format_field('owner name', self.owner_name),
        format_field('organisation id', self.organisation_id),
        format_field('organisation name', self.organisation_name),
    ]

    org_details = self.owner_organisation_details
    org_fields = [
        format_field('owner id', org_details.owner_id),
        format_field('owner name', org_details.owner_name),
        format_field('enterprise id', org_details.enterprise_id),
        format_field('enterprise name', org_details.enterprise_name),
    ]

    sub_orgs = org_details.organisations
    if sub_orgs:
        sub_org_str = '\n    '.join(
            f'organisation id: {org.organisation_id}\n'
            f'    organisation name: {org.organisation_name}'
            for org in sub_orgs
        )
        org_fields.append(f'sub-organisations:\n    {sub_org_str}')
    else:
        org_fields.append('sub-organisations: None')

    return (
        '\n'.join(main_fields) + '\nowner organisation details:\n  ' + '\n  '.join(org_fields)
    )

add

add(
    entity: str | tuple[str, str],
    context: dict | None = None,
) -> ListEntityOperationResponse

Add an entity to a list.

PARAMETER DESCRIPTION
entity

ID or (name, type) tuple of the entity to add.

TYPE: str | tuple[str, str]

context

Context object for the entity.

TYPE: dict | None DEFAULT: None

Endpoint

list/{id}/entity/add

RAISES DESCRIPTION
ValidationError

if any supplied parameter is of incorrect type.

ListApiError

If connection error occurs.

RETURNS DESCRIPTION
ListEntityOperationResponse

Response from the list/{id}/entity/add endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@validate_call
def add(
    self,
    entity: Annotated[
        str | tuple[str, str], Doc('ID or (name, type) tuple of the entity to add.')
    ],
    context: Annotated[dict | None, Doc('Context object for the entity.')] = None,
) -> Annotated[
    ListEntityOperationResponse, Doc('Response from the `list/{id}/entity/add` endpoint.')
]:
    """Add an entity to a list.

    Endpoint:
        `list/{id}/entity/add`

    Raises:
        ValidationError: if any supplied parameter is of incorrect type.
        ListApiError: If connection error occurs.
    """
    return self._list_op(entity, ADD_OP, context=context or {})

bulk_add

bulk_add(entities: list[str | tuple[str, str]]) -> dict

Bulk add entities to a list.

Adds entities one at a time due to List API requirement. Logs progress every 10%.

PARAMETER DESCRIPTION
entities

List of entity string IDs or (name, type) tuples to add.

TYPE: list[str | tuple[str, str]]

Endpoint

list/{id}/entity/add

RAISES DESCRIPTION
ValidationError

If any supplied parameter is of incorrect type.

ValueError

If an invalid operation is supplied.

ListApiError

If connection error occurs.

RETURNS DESCRIPTION
dict

Results JSON with 'added', 'unchanged', and 'error' keys containing lists of entities.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@validate_call
def bulk_add(
    self,
    entities: Annotated[
        list[str | tuple[str, str]],
        Doc('List of entity string IDs or (name, type) tuples to add.'),
    ],
) -> Annotated[
    dict,
    Doc(
        "Results JSON with 'added', 'unchanged', and 'error' keys containing lists of entities."
    ),
]:
    """Bulk add entities to a list.

    Adds entities one at a time due to List API requirement. Logs progress every 10%.

    Endpoint:
        `list/{id}/entity/add`

    Raises:
        ValidationError: If any supplied parameter is of incorrect type.
        ValueError: If an invalid operation is supplied.
        ListApiError: If connection error occurs.
    """
    result = self._bulk_op(entities, ADD_OP)
    status = self.status()
    while status.status != 'ready':
        self.log.info(f"Awaiting list 'ready' status, current status '{status.status}'")
        status = self.status()
        time.sleep(IS_READY_INCREMENT)

    return result

bulk_remove

bulk_remove(entities: list[str | tuple[str, str]]) -> dict

Bulk remove entities from a list.

Removes entities one at a time due to List API requirement. Logs progress every 10%.

PARAMETER DESCRIPTION
entities

List of entity string IDs or (name, type) tuples to remove.

TYPE: list[str | tuple[str, str]]

Endpoint

list/{id}/entity/remove

RAISES DESCRIPTION
ValidationError

If any supplied parameter is of incorrect type.

ValueError

If an invalid operation is supplied.

ListApiError

If connection error occurs.

RETURNS DESCRIPTION
dict

Results JSON with 'removed', 'unchanged', and 'error' keys with the lists of entities.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@validate_call
def bulk_remove(
    self,
    entities: Annotated[
        list[str | tuple[str, str]],
        Doc('List of entity string IDs or (name, type) tuples to remove.'),
    ],
) -> Annotated[
    dict,
    Doc(
        "Results JSON with 'removed', 'unchanged', and 'error' keys with the lists of entities."
    ),
]:
    """Bulk remove entities from a list.

    Removes entities one at a time due to List API requirement. Logs progress every 10%.

    Endpoint:
        `list/{id}/entity/remove`

    Raises:
        ValidationError: If any supplied parameter is of incorrect type.
        ValueError: If an invalid operation is supplied.
        ListApiError: If connection error occurs.
    """
    result = self._bulk_op(entities, REMOVE_OP)
    status = self.status()
    while status.status != 'ready':
        self.log.info(f"Awaiting list 'ready' status, current status '{status.status}'")
        status = self.status()
        time.sleep(IS_READY_INCREMENT)

    return result

entities

entities() -> list[ListEntity]

Get entities for a list.

Endpoint

list/{id}/entities

RAISES DESCRIPTION
ListApiError

If connection error occurs.

RETURNS DESCRIPTION
list[ListEntity]

Response from the list/{id}/entities endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def entities(
    self,
) -> Annotated[list[ListEntity], Doc('Response from the `list/{id}/entities` endpoint.')]:
    """Get entities for a list.

    Endpoint:
        `list/{id}/entities`

    Raises:
        ListApiError: If connection error occurs.
    """
    url = EP_LIST + '/' + self.id_ + '/entities'
    response = self.rf_client.request('get', url)
    return validate_list(ListEntity, response.json(), id_path='entity.name', log=self.log)

entities_with_tags

entities_with_tags() -> list[ListEntityWithTags]

Get entities for a list, together with their list-specific tags.

Tags are not free-text. They are a fixed set of 57 predefined values, so arbitrary tag strings cannot be expected. See https://docs.recordedfuture.com/reference/lists-available-tags for the full list of valid tags, their display names, and their API values.

tags is only populated for lists whose type has tagging enabled server-side (currently Third-Parties Watch Lists). A list of any other type returns its entities with an empty tags list rather than an error, so an empty tags does not indicate a failure. A list whose type supports tagging but which has not yet been migrated server-side responds 400 instead.

Endpoint

list/{id}/entitiesWithTags

RAISES DESCRIPTION
ListApiError

If connection error occurs. The API responds 400 if the list's type supports tagging but the list has not been migrated to support tags, and 404 if the list does not exist.

RETURNS DESCRIPTION
list[ListEntityWithTags]

Response from the list/{id}/entitiesWithTags endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def entities_with_tags(
    self,
) -> Annotated[
    list[ListEntityWithTags],
    Doc('Response from the `list/{id}/entitiesWithTags` endpoint.'),
]:
    """Get entities for a list, together with their list-specific tags.

    Tags are **not** free-text. They are a fixed set of 57 predefined values, so arbitrary
    tag strings cannot be expected. See
    https://docs.recordedfuture.com/reference/lists-available-tags for the full list of valid
    tags, their display names, and their API values.

    `tags` is only populated for lists whose type has tagging enabled server-side (currently
    Third-Parties Watch Lists). A list of any other type returns its entities with an empty
    `tags` list rather than an error, so an empty `tags` does not indicate a failure. A list
    whose type supports tagging but which has not yet been migrated server-side responds 400
    instead.

    Endpoint:
        `list/{id}/entitiesWithTags`

    Raises:
        ListApiError: If connection error occurs. The API responds 400 if the list's type
            supports tagging but the list has not been migrated to support tags, and 404 if
            the list does not exist.
    """
    url = EP_LIST_ENTITIES_WITH_TAGS.format(self.id_)
    response = self.rf_client.request('get', url)
    return validate_list(
        ListEntityWithTags, response.json(), id_path='entity.name', log=self.log
    )

info

info() -> ListInfoOut

Get info for a list.

Endpoint

list/{id}/info

RAISES DESCRIPTION
ListApiError

If connection error occurs.

RETURNS DESCRIPTION
ListInfoOut

Response from the list/{id}/info endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def info(self) -> Annotated[ListInfoOut, Doc('Response from the `list/{id}/info` endpoint.')]:
    """Get info for a list.

    Endpoint:
        `list/{id}/info`

    Raises:
        ListApiError: If connection error occurs.
    """
    self.log.debug(f"Getting list status for '{self.name}'")
    url = EP_LIST + f'/{self.id_}/info'
    response = self.rf_client.request('get', url)
    return ListInfoOut.model_validate(response.json())

json

json(
    by_alias: bool = True,
    exclude_none: bool = True,
    auto_exclude_unset: bool = True,
    **kwargs,
)

JSON representation of models. It is inherited by every model.

PARAMETER DESCRIPTION
by_alias

Alias flag:

  • If True, writes fields with their API alias (e.g., IpAddress)
  • If False uses the Python attribute name alias.

TYPE: bool DEFAULT: True

exclude_none

Whether to exclude fields equal to None.

TYPE: bool DEFAULT: True

auto_exclude_unset

Whether to auto exclude values not set.

  • If True, uses RF_EXTRA_MODEL config to decide inclusion of unmapped fields.
  • If False, you must specify exclude_unset manually.

TYPE: bool DEFAULT: True

Source code in psengine/common_models.py
def json(
    self,
    by_alias: Annotated[
        bool,
        Doc(
            """
            Alias flag:

            - If `True`, writes fields with their API alias (e.g., `IpAddress`)
            - If `False` uses the Python attribute name alias.
            """
        ),
    ] = True,
    exclude_none: Annotated[bool, Doc('Whether to exclude fields equal to None.')] = True,
    auto_exclude_unset: Annotated[
        bool,
        Doc("""
            Whether to auto exclude values not set.

            - If `True`, uses `RF_EXTRA_MODEL` config to decide inclusion of unmapped fields.
            - If `False`, you must specify `exclude_unset` manually.
            """),
    ] = True,
    **kwargs,
):
    """JSON representation of models. It is inherited by every model."""
    if not auto_exclude_unset and kwargs.get('exclude_unset') is None:
        raise ValueError('`auto_exclude_unset` is False, `exclude_unset has to be provided`')

    exclude_unset = (
        bool(self.model_config['extra'] != 'allow')
        if auto_exclude_unset
        else kwargs['exclude_unset']
    )
    kwargs['exclude_unset'] = exclude_unset
    return self.model_dump(mode='json', by_alias=by_alias, exclude_none=exclude_none, **kwargs)

remove

remove(
    entity: str | tuple[str, str],
) -> ListEntityOperationResponse

Remove an entity from a list.

PARAMETER DESCRIPTION
entity

ID or (name, type) tuple of the entity to remove.

TYPE: str | tuple[str, str]

Endpoint

list/{id}/entity/remove

RAISES DESCRIPTION
ValidationError

if any supplied parameter is of incorrect type.

ListApiError

If connection error occurs.

RETURNS DESCRIPTION
ListEntityOperationResponse

Response from the list/{id}/entity/remove endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@validate_call
def remove(
    self,
    entity: Annotated[
        str | tuple[str, str], Doc('ID or (name, type) tuple of the entity to remove.')
    ],
) -> Annotated[
    ListEntityOperationResponse, Doc('Response from the `list/{id}/entity/remove` endpoint.')
]:
    """Remove an entity from a list.

    Endpoint:
        `list/{id}/entity/remove`

    Raises:
        ValidationError: if any supplied parameter is of incorrect type.
        ListApiError: If connection error occurs.
    """
    return self._list_op(entity, REMOVE_OP)

status

status() -> ListStatusOut

Get status information about list.

Endpoint

list/{id}/status

RAISES DESCRIPTION
ListApiError

if connection error occurs

RETURNS DESCRIPTION
ListStatusOut

list/{id}/status response

TYPE: ListStatusOut

Source code in psengine/entity_lists/entity_list.py
@debug_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def status(self) -> ListStatusOut:
    """Get status information about list.

    Endpoint:
        `list/{id}/status`

    Raises:
        ListApiError: if connection error occurs

    Returns:
        ListStatusOut: list/{id}/status response
    """
    self.log.debug(f"Getting list status for '{self.name}'")
    url = EP_LIST + f'/{self.id_}/status'
    response = self.rf_client.request('get', url)
    validated_status = ListStatusOut.model_validate(response.json())
    self.log.debug(
        f"List '{self.name}' status: {validated_status.status}, "
        f'entities: {validated_status.size}'
    )

    return validated_status

text_entries

text_entries() -> list[str]

Get text entries for a list.

Endpoint

list/{id}/textEntries

RAISES DESCRIPTION
ListApiError

If connection error occurs.

RETURNS DESCRIPTION
list[str]

Response from the list/{id}/textEntries endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def text_entries(
    self,
) -> Annotated[list[str], Doc('Response from the `list/{id}/textEntries` endpoint.')]:
    """Get text entries for a list.

    Endpoint:
        `list/{id}/textEntries`

    Raises:
        ListApiError: If connection error occurs.
    """
    url = EP_LIST + '/' + self.id_ + '/textEntries'
    return self.rf_client.request('get', url).json()

update_entity_tags

update_entity_tags(
    entity: str | tuple[str, str], tags: list[str]
) -> ReplaceEntityTagsOut

Replace all tags on an entity in a list.

This replaces rather than appends: tags becomes the entity's complete tag set, and passing an empty list clears every tag from it.

Tags are not free-text. They are a fixed set of 57 predefined values - pass them as plain strings or as ListTagName members. Invalid names are rejected by the API with a 400. See https://docs.recordedfuture.com/reference/lists-available-tags for the full list.

Tagging is only enabled for lists whose type supports it (currently Third-Parties Watch Lists); other list types respond 403.

If entity is a (name, type) tuple that cannot be resolved, the returned operation is an EntityNotResolvedOperation rather than an exception, matching add and remove.

PARAMETER DESCRIPTION
entity

ID or (name, type) tuple of the entity to tag.

TYPE: str | tuple[str, str]

tags

Complete set of tags to apply. Replaces every tag already on the entity.

TYPE: list[str]

Endpoint

list/{id}/entity/tags

RAISES DESCRIPTION
ValidationError

if any supplied parameter is of incorrect type.

ListApiError

If connection error occurs. The API responds 400 for an invalid tag name, entity, or list, 403 if tag updates are not enabled for the list type, and 404 if the entity is not on the list.

RETURNS DESCRIPTION
ReplaceEntityTagsOut

Response from the list/{id}/entity/tags endpoint.

Source code in psengine/entity_lists/entity_list.py
@debug_call
@validate_call
@connection_exceptions(ignore_status_code=[], exception_to_raise=ListApiError)
def update_entity_tags(
    self,
    entity: Annotated[
        str | tuple[str, str], Doc('ID or (name, type) tuple of the entity to tag.')
    ],
    tags: Annotated[
        list[str],
        Doc('Complete set of tags to apply. Replaces every tag already on the entity.'),
    ],
) -> Annotated[
    ReplaceEntityTagsOut, Doc('Response from the `list/{id}/entity/tags` endpoint.')
]:
    """Replace all tags on an entity in a list.

    This **replaces** rather than appends: `tags` becomes the entity's complete tag set,
    and passing an empty list clears every tag from it.

    Tags are **not** free-text. They are a fixed set of 57 predefined values - pass them as
    plain strings or as `ListTagName` members. Invalid names are rejected by the API with a
    400. See https://docs.recordedfuture.com/reference/lists-available-tags for the full
    list.

    Tagging is only enabled for lists whose type supports it (currently Third-Parties Watch
    Lists); other list types respond 403.

    If `entity` is a `(name, type)` tuple that cannot be resolved, the returned
    `operation` is an `EntityNotResolvedOperation` rather than an exception, matching
    `add` and `remove`.

    Endpoint:
        `list/{id}/entity/tags`

    Raises:
        ValidationError: if any supplied parameter is of incorrect type.
        ListApiError: If connection error occurs. The API responds 400 for an invalid tag
            name, entity, or list, 403 if tag updates are not enabled for the list type,
            and 404 if the entity is not on the list.
    """
    if isinstance(entity, str):
        resolved_entity_id = entity
    else:
        resolved_entity = self.match_mgr.resolve_entity_id(entity[0], entity_type=entity[1])
        if not resolved_entity.is_found:
            return ReplaceEntityTagsOut(
                operation=EntityNotResolvedOperation(
                    status='entity_not_resolved', message=str(resolved_entity.content)
                )
            )
        resolved_entity_id = resolved_entity.content.id_

    request_body = {'entity': {'id': resolved_entity_id}, 'tags': tags}
    ReplaceEntityTagsIn.model_validate(request_body)

    url = EP_LIST_ENTITY_TAGS.format(self.id_)
    response = self.rf_client.request('post', url, data=request_body)
    return ReplaceEntityTagsOut.model_validate(response.json())

ListEntity

Bases: RFBaseModel

Validate data received from /{listId}/entities endpoint.

added instance-attribute

added: datetime

context class-attribute instance-attribute

context: dict | None = None

entity instance-attribute

entity: IdNameType

model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra=get('RF_MODEL_EXTRA', 'ignore')
)

status instance-attribute

status: str

__eq__

__eq__(other: ListEntity)
Source code in psengine/entity_lists/entity_list.py
def __eq__(self, other: 'ListEntity'):
    return self.entity.id_ == other.entity.id_

__gt__

__gt__(other: ListEntity)
Source code in psengine/entity_lists/entity_list.py
def __gt__(self, other: 'ListEntity'):
    return (self.entity.name, self.added) > (other.entity.name, other.added)

__hash__

__hash__()
Source code in psengine/entity_lists/entity_list.py
def __hash__(self):
    return hash(self.entity.id_)

__str__

__str__()
Source code in psengine/entity_lists/entity_list.py
def __str__(self):
    return (
        f'{self.entity.type_}: {self.entity.name}, added {self.added.strftime(TIMESTAMP_STR)}'
    )

json

json(
    by_alias: bool = True,
    exclude_none: bool = True,
    auto_exclude_unset: bool = True,
    **kwargs,
)

JSON representation of models. It is inherited by every model.

PARAMETER DESCRIPTION
by_alias

Alias flag:

  • If True, writes fields with their API alias (e.g., IpAddress)
  • If False uses the Python attribute name alias.

TYPE: bool DEFAULT: True

exclude_none

Whether to exclude fields equal to None.

TYPE: bool DEFAULT: True

auto_exclude_unset

Whether to auto exclude values not set.

  • If True, uses RF_EXTRA_MODEL config to decide inclusion of unmapped fields.
  • If False, you must specify exclude_unset manually.

TYPE: bool DEFAULT: True

Source code in psengine/common_models.py
def json(
    self,
    by_alias: Annotated[
        bool,
        Doc(
            """
            Alias flag:

            - If `True`, writes fields with their API alias (e.g., `IpAddress`)
            - If `False` uses the Python attribute name alias.
            """
        ),
    ] = True,
    exclude_none: Annotated[bool, Doc('Whether to exclude fields equal to None.')] = True,
    auto_exclude_unset: Annotated[
        bool,
        Doc("""
            Whether to auto exclude values not set.

            - If `True`, uses `RF_EXTRA_MODEL` config to decide inclusion of unmapped fields.
            - If `False`, you must specify `exclude_unset` manually.
            """),
    ] = True,
    **kwargs,
):
    """JSON representation of models. It is inherited by every model."""
    if not auto_exclude_unset and kwargs.get('exclude_unset') is None:
        raise ValueError('`auto_exclude_unset` is False, `exclude_unset has to be provided`')

    exclude_unset = (
        bool(self.model_config['extra'] != 'allow')
        if auto_exclude_unset
        else kwargs['exclude_unset']
    )
    kwargs['exclude_unset'] = exclude_unset
    return self.model_dump(mode='json', by_alias=by_alias, exclude_none=exclude_none, **kwargs)

ListEntityWithTags

Bases: ListEntity

Validate data received from /{listId}/entitiesWithTags endpoint.

Identical to ListEntity, with the addition of the list-specific tags assigned to the entity. Tags are predefined and only populated for lists whose type has tagging enabled - see ListEntityTag.

added instance-attribute

added: datetime

context class-attribute instance-attribute

context: dict | None = None

entity instance-attribute

entity: IdNameType

model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra=get('RF_MODEL_EXTRA', 'ignore')
)

status instance-attribute

status: str

tags class-attribute instance-attribute

tags: list[ListEntityTag] = []

__eq__

__eq__(other: ListEntity)
Source code in psengine/entity_lists/entity_list.py
def __eq__(self, other: 'ListEntity'):
    return self.entity.id_ == other.entity.id_

__gt__

__gt__(other: ListEntity)
Source code in psengine/entity_lists/entity_list.py
def __gt__(self, other: 'ListEntity'):
    return (self.entity.name, self.added) > (other.entity.name, other.added)

__hash__

__hash__()
Source code in psengine/entity_lists/entity_list.py
def __hash__(self):
    return hash(self.entity.id_)

__str__

__str__()
Source code in psengine/entity_lists/entity_list.py
def __str__(self):
    return (
        f'{self.entity.type_}: {self.entity.name}, added {self.added.strftime(TIMESTAMP_STR)}'
    )

json

json(
    by_alias: bool = True,
    exclude_none: bool = True,
    auto_exclude_unset: bool = True,
    **kwargs,
)

JSON representation of models. It is inherited by every model.

PARAMETER DESCRIPTION
by_alias

Alias flag:

  • If True, writes fields with their API alias (e.g., IpAddress)
  • If False uses the Python attribute name alias.

TYPE: bool DEFAULT: True

exclude_none

Whether to exclude fields equal to None.

TYPE: bool DEFAULT: True

auto_exclude_unset

Whether to auto exclude values not set.

  • If True, uses RF_EXTRA_MODEL config to decide inclusion of unmapped fields.
  • If False, you must specify exclude_unset manually.

TYPE: bool DEFAULT: True

Source code in psengine/common_models.py
def json(
    self,
    by_alias: Annotated[
        bool,
        Doc(
            """
            Alias flag:

            - If `True`, writes fields with their API alias (e.g., `IpAddress`)
            - If `False` uses the Python attribute name alias.
            """
        ),
    ] = True,
    exclude_none: Annotated[bool, Doc('Whether to exclude fields equal to None.')] = True,
    auto_exclude_unset: Annotated[
        bool,
        Doc("""
            Whether to auto exclude values not set.

            - If `True`, uses `RF_EXTRA_MODEL` config to decide inclusion of unmapped fields.
            - If `False`, you must specify `exclude_unset` manually.
            """),
    ] = True,
    **kwargs,
):
    """JSON representation of models. It is inherited by every model."""
    if not auto_exclude_unset and kwargs.get('exclude_unset') is None:
        raise ValueError('`auto_exclude_unset` is False, `exclude_unset has to be provided`')

    exclude_unset = (
        bool(self.model_config['extra'] != 'allow')
        if auto_exclude_unset
        else kwargs['exclude_unset']
    )
    kwargs['exclude_unset'] = exclude_unset
    return self.model_dump(mode='json', by_alias=by_alias, exclude_none=exclude_none, **kwargs)

ListInfoOut

Bases: RFBaseModel

Validate data received from /{listId}/info endpoint.

created instance-attribute

created: datetime

id_ class-attribute instance-attribute

id_: str = Field(alias='id')

model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra=get('RF_MODEL_EXTRA', 'ignore')
)

name instance-attribute

name: str

organisation_id class-attribute instance-attribute

organisation_id: str | None = None

organisation_name class-attribute instance-attribute

organisation_name: str | None = None

owner_id instance-attribute

owner_id: str

owner_name instance-attribute

owner_name: str

owner_organisation_details class-attribute instance-attribute

owner_organisation_details: OwnerOrganisationDetails = (
    Field(default_factory=OwnerOrganisationDetails)
)

type_ class-attribute instance-attribute

type_: str = Field(alias='type')

updated instance-attribute

updated: datetime

json

json(
    by_alias: bool = True,
    exclude_none: bool = True,
    auto_exclude_unset: bool = True,
    **kwargs,
)

JSON representation of models. It is inherited by every model.

PARAMETER DESCRIPTION
by_alias

Alias flag:

  • If True, writes fields with their API alias (e.g., IpAddress)
  • If False uses the Python attribute name alias.

TYPE: bool DEFAULT: True

exclude_none

Whether to exclude fields equal to None.

TYPE: bool DEFAULT: True

auto_exclude_unset

Whether to auto exclude values not set.

  • If True, uses RF_EXTRA_MODEL config to decide inclusion of unmapped fields.
  • If False, you must specify exclude_unset manually.

TYPE: bool DEFAULT: True

Source code in psengine/common_models.py
def json(
    self,
    by_alias: Annotated[
        bool,
        Doc(
            """
            Alias flag:

            - If `True`, writes fields with their API alias (e.g., `IpAddress`)
            - If `False` uses the Python attribute name alias.
            """
        ),
    ] = True,
    exclude_none: Annotated[bool, Doc('Whether to exclude fields equal to None.')] = True,
    auto_exclude_unset: Annotated[
        bool,
        Doc("""
            Whether to auto exclude values not set.

            - If `True`, uses `RF_EXTRA_MODEL` config to decide inclusion of unmapped fields.
            - If `False`, you must specify `exclude_unset` manually.
            """),
    ] = True,
    **kwargs,
):
    """JSON representation of models. It is inherited by every model."""
    if not auto_exclude_unset and kwargs.get('exclude_unset') is None:
        raise ValueError('`auto_exclude_unset` is False, `exclude_unset has to be provided`')

    exclude_unset = (
        bool(self.model_config['extra'] != 'allow')
        if auto_exclude_unset
        else kwargs['exclude_unset']
    )
    kwargs['exclude_unset'] = exclude_unset
    return self.model_dump(mode='json', by_alias=by_alias, exclude_none=exclude_none, **kwargs)

ListStatusOut

Bases: RFBaseModel

Validate data received from /{listId}/status endpoint.

model_config class-attribute instance-attribute

model_config = ConfigDict(
    extra=get('RF_MODEL_EXTRA', 'ignore')
)

size instance-attribute

size: int

status instance-attribute

status: str

json

json(
    by_alias: bool = True,
    exclude_none: bool = True,
    auto_exclude_unset: bool = True,
    **kwargs,
)

JSON representation of models. It is inherited by every model.

PARAMETER DESCRIPTION
by_alias

Alias flag:

  • If True, writes fields with their API alias (e.g., IpAddress)
  • If False uses the Python attribute name alias.

TYPE: bool DEFAULT: True

exclude_none

Whether to exclude fields equal to None.

TYPE: bool DEFAULT: True

auto_exclude_unset

Whether to auto exclude values not set.

  • If True, uses RF_EXTRA_MODEL config to decide inclusion of unmapped fields.
  • If False, you must specify exclude_unset manually.

TYPE: bool DEFAULT: True

Source code in psengine/common_models.py
def json(
    self,
    by_alias: Annotated[
        bool,
        Doc(
            """
            Alias flag:

            - If `True`, writes fields with their API alias (e.g., `IpAddress`)
            - If `False` uses the Python attribute name alias.
            """
        ),
    ] = True,
    exclude_none: Annotated[bool, Doc('Whether to exclude fields equal to None.')] = True,
    auto_exclude_unset: Annotated[
        bool,
        Doc("""
            Whether to auto exclude values not set.

            - If `True`, uses `RF_EXTRA_MODEL` config to decide inclusion of unmapped fields.
            - If `False`, you must specify `exclude_unset` manually.
            """),
    ] = True,
    **kwargs,
):
    """JSON representation of models. It is inherited by every model."""
    if not auto_exclude_unset and kwargs.get('exclude_unset') is None:
        raise ValueError('`auto_exclude_unset` is False, `exclude_unset has to be provided`')

    exclude_unset = (
        bool(self.model_config['extra'] != 'allow')
        if auto_exclude_unset
        else kwargs['exclude_unset']
    )
    kwargs['exclude_unset'] = exclude_unset
    return self.model_dump(mode='json', by_alias=by_alias, exclude_none=exclude_none, **kwargs)