Source code for cybsi.api.observable.entity
from datetime import datetime
from typing import Iterable, List, Optional, Tuple
from uuid import UUID
from ..internal import (
JsonObject,
JsonObjectForm,
JsonObjectView,
parse_rfc3339_timestamp,
)
from .aggregate_section import (
AttributeValuableFactView,
AttributeValueView,
SectionsView,
_convert_attribute_value_type,
)
from .enums import AttributeNames, EntityKeyTypes, EntityTypes
from .view import AbstractEntityView
[docs]
class EntityKeyView(JsonObjectView):
"""Entity key view."""
@property
def type(self) -> EntityKeyTypes:
"""Entity key type."""
return EntityKeyTypes(self._get("type"))
@property
def value(self) -> str:
"""Entity key value.
Type depends on key type.
"""
return self._get("value")
[docs]
class EntityView(AbstractEntityView):
"""Default and complete entity view.
Includes entity types and natural keys.
.. versionadded:: 2.9
"""
@classmethod
def _view_uuid(cls) -> UUID:
# The default entity view has no view uuid
return None # type: ignore
@property
def uuid(self) -> UUID:
"""Entity UUID."""
return UUID(self._get("uuid"))
@property
def url(self) -> Optional[str]:
"""URL of the entity in API.
Property is presented if :class:`~cybsi.api.client.Config`
embed_object_url is True.
"""
return self._get_optional("url")
@property
def type(self) -> EntityTypes:
"""Entity type."""
return EntityTypes(self._get("type"))
@property
def keys(self) -> List[EntityKeyView]:
"""Entity natural keys."""
return [EntityKeyView(x) for x in self._get("keys")]
[docs]
class EntityAggregateView(EntityView):
"""Entity aggregated view."""
@property
def sections(self) -> SectionsView:
"""Entity aggregated sections."""
return SectionsView(self._get("sections"))
@property
def first_seen(self) -> datetime:
"""Date and time when entity was first mentioned in the observations"""
return parse_rfc3339_timestamp(self._get("firstSeen"))
@property
def last_seen(self) -> datetime:
"""Date and time when entity was last mentioned in the observations"""
return parse_rfc3339_timestamp(self._get("lastSeen"))
[docs]
class EntityAttributeForecastView(JsonObjectView):
"""Entity attribute forecast view."""
def __init__(self, data: JsonObject, attribute_name: AttributeNames):
super().__init__(data)
self._attribute_name = attribute_name
@property
def has_conflicts(self) -> bool:
"""Entity has conflicting facts about attribute."""
return self._get("hasConflicts")
@property
def values(self) -> List["AttributeForecastView"]:
"""Attribute values forecast in descending order of confidence."""
return [
AttributeForecastView(x, self._attribute_name) for x in self._get("values")
]
[docs]
class AttributeForecastView(JsonObjectView):
"""Single attribute value forecast."""
def __init__(self, data: JsonObject, attribute_name: AttributeNames):
super().__init__(data)
self._attribute_name = attribute_name
@property
def value(self) -> AttributeValueView:
"""Return value type depends on attribute.
Note:
Return :class:`~cybsi.api.RefView` type
is used to get the value of a dictionary item attribute.
You can resolve the ref
using :meth:`~cybsi.api.dictionary.DictionariesAPI.view_item`.
"""
return _convert_attribute_value_type(self._attribute_name, self._get("value"))
@property
def confidence(self) -> float:
"""Confidence of forecast."""
return self._get("confidence")
@property
def valuable_facts(self) -> Optional[List[AttributeValuableFactView]]:
"""List of forecast valuable facts in descending order of confidence."""
values = self._get_optional("valuableFacts")
if values is not None:
return [
AttributeValuableFactView(value, self._attribute_name)
for value in values
]
return None