colander_data_converter.base.models

class colander_data_converter.base.models.Actor[source]

Bases: Entity

Actor represents an individual or group involved in an event, activity, or system.

This class extends the Entity base class and includes additional fields specific to actors.

Example

>>> actor_type = ActorTypes.INDIVIDUAL.value
>>> actor = Actor(
...     name='John Doe',
...     type=actor_type
... )
>>> print(actor.name)
John Doe
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: ActorType [Required]

The type definition for the actor.

field colander_internal_type: Literal['actor'] = 'actor'

Internal type discriminator for (de)serialization.

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the device.

class colander_data_converter.base.models.Artifact[source]

Bases: Entity

Artifact represents a file or data object, such as a document, image, or binary, within the system.

This class extends the Entity base class and includes additional fields specific to artifacts, such as type, attributes, extraction source, file metadata, and cryptographic hashes.

Example

>>> artifact_type = ArtifactTypes.DOCUMENT.value
>>> device_type = DeviceTypes.LAPTOP.value
>>> device = Device(name='Analyst Laptop', type=device_type)
>>> artifact = Artifact(
...     name='malware_sample.pdf',
...     type=artifact_type,
...     extracted_from=device,
...     extension='pdf',
...     original_name='invoice.pdf',
...     mime_type='application/pdf',
...     md5='d41d8cd98f00b204e9800998ecf8427e',
...     sha1='da39a3ee5e6b4b0d3255bfef95601890afd80709',
...     sha256='e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
...     size_in_bytes=12345
... )
>>> print(artifact.name)
malware_sample.pdf
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: ArtifactType [Required]

The type definition for the artifact.

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the artifact.

field extracted_from: Device | None | ObjectReference = None

Reference to the device from which this artifact was extracted.

field extension: str | None = None

The file extension of the artifact, if applicable.

field original_name: str | None = None

The original name of the artifact before ingestion.

field mime_type: str | None = None

The MIME type of the artifact.

field detached_signature: str | None = None

Optional detached signature for the artifact.

field md5: str | None = None

MD5 hash of the artifact.

field sha1: str | None = None

SHA1 hash of the artifact.

field sha256: str | None = None

SHA256 hash of the artifact.

field size_in_bytes: Annotated[int, Ge(ge=0)] = 0

The size of the artifact in bytes.

Constraints:
  • ge = 0

field colander_internal_type: Literal['artifact'] = 'artifact'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.Case[source]

Bases: ColanderType

Case represents a collection or grouping of related entities, artifacts, or events.

This class is used to organize and manage related data, such as incidents, investigations, or projects.

Example

>>> case = Case(
...     name='Investigation Alpha',
...     description='Investigation of suspicious activity'
... )
>>> print(case.name)
Investigation Alpha
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field id: Annotated[UUID, UuidVersion(uuid_version=4)] [Optional]

The unique identifier for the case.

Constraints:
  • uuid_version = 4

field created_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 540016, tzinfo=datetime.timezone.utc)

The timestamp when the case was created.

field updated_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 540040, tzinfo=datetime.timezone.utc)

The timestamp when the case was last updated.

field name: str [Required]

The name of the case.

Constraints:
  • min_length = 1

  • max_length = 512

field description: str [Required]

A description of the case.

Constraints:
  • min_length = 1

field documentation: str | None = None

Optional documentation or notes for the case.

field pap: TlpPapLevel = WHITE

The PAP (Permissible Actions Protocol) level for the case.

field parent_case: Case | None | ObjectReference = None

Reference to a parent case, if this case is a sub-case.

field tlp: TlpPapLevel = WHITE

The TLP (Traffic Light Protocol) level for the case.

field colander_internal_type: Literal['case'] = 'case'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.ColanderFeed[source]

Bases: ColanderType

ColanderFeed aggregates entities, relations, and cases for bulk operations or data exchange.

This class is used to load, manage, and resolve references for collections of model objects.

Example

>>> feed_data = {
...     "entities": {
...         "204d4590-a3ee-4f24-8eaf-350ec2fa751b": {
...             "id": "204d4590-a3ee-4f24-8eaf-350ec2fa751b",
...             "name": "Example Observable",
...             "type": {"name": "IPv4", "short_name": "IPV4"},
...             "super_type": {"short_name": "observable"},
...             "colander_internal_type": "observable"
...         }
...     },
...     "relations": {},
...     "cases": {}
... }
>>> feed = ColanderFeed.load(feed_data)
>>> print(list(feed.entities.keys()))
['204d4590-a3ee-4f24-8eaf-350ec2fa751b']
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field id: Annotated[UUID, UuidVersion(uuid_version=4)] [Optional]

The unique identifier for the feed.

Constraints:
  • uuid_version = 4

field name: str = ''

Optional name of the feed.

field description: str = ''

Optional description of the feed.

field entities: Dict[str, Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator='colander_internal_type')]] | None = {}

Dictionary of entity objects, keyed by their IDs.

field relations: Dict[str, EntityRelation] | None = {}

Dictionary of entity relations, keyed by their IDs.

field cases: Dict[str, Case] | None = {}

Dictionary of case objects, keyed by their IDs.

static load(raw_object)[source]

Loads an EntityFeed from a raw object, which can be either a dictionary or a list.

Parameters:

raw_object (dict | list) – The raw data representing the entities and relations to be loaded into the EntityFeed.

Returns:

The EntityFeed loaded from a raw object.

Raises:

ValueError – If there are inconsistencies in entity IDs or relations.

Return type:

ColanderFeed

resolve_references(strict=False)[source]

Resolves references within entities, relations, and cases.

Iterates over each entity, relation, and case within the respective collections, calling their resolve_references method to update them with any referenced data. This helps in synchronizing internal state with external dependencies or updates.

Parameters:

strict – If True, raises a ValueError when a UUID reference cannot be resolved. If False, unresolved references remain as UUIDs.

Unlinks references from all entities, relations, and cases within the current context.

This method iterates through each entity, relation, and case stored in the entities, relations, and cases dictionaries respectively, invoking their unlink_references() methods to clear any references held by these objects. This operation is useful for breaking dependencies or preparing data for deletion or modification.

contains(obj)[source]

Check if an object exists in the current feed by its identifier.

This method determines whether a given object (or its identifier) exists within any of the feed’s collections: entities, relations, or cases. It extracts the object’s ID and searches across all three collections.

Parameters:

obj (Any) – The object to check for existence. Can be: - An entity, relation, or case object with an ‘id’ attribute - A string or UUID representing an object ID - Any object that can be processed by get_id()

Returns:

True if the object exists in entities, relations, or cases; False otherwise

Return type:

bool

Example

>>> feed = ColanderFeed()
>>> obs = Observable(name="test", type=ObservableTypes.IPV4.value)
>>> feed.entities[str(obs.id)] = obs
>>> feed.contains(obs)
True
>>> feed.contains("nonexistent-id")
False
get(obj)[source]

Retrieve an object from the feed by its identifier.

This method searches for an object across all feed collections (entities, relations, cases) using the object’s ID. It first checks if the object exists using the contains() method, then attempts to retrieve it from the appropriate collection.

Parameters:

obj (Any) – The object to retrieve. Can be: - An entity, relation, or case object with an ‘id’ attribute - A string or UUID representing an object ID - Any object that can be processed by get_id()

Returns:

The found object if it exists in any of the collections (entities, relations, or cases), otherwise None.

Return type:

Optional[Union[Case, EntityTypes, EntityRelation]]

get_by_super_type(super_type)[source]
Return type:

List[Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator=’colander_internal_type’)]]

get_incoming_relations(entity)[source]

Retrieve all relations where the specified entity is the target (obj_to).

This method finds all entity relations in the feed where the given entity is the destination or target of the relationship. Only fully resolved relations are considered to ensure data consistency.

Parameters:

entity (EntityTypes) – The entity to find incoming relations for. Must be an instance of Entity.

Returns:

A dictionary mapping relation IDs to EntityRelation objects where the entity is the target (obj_to).

Return type:

Dict[str, EntityRelation]

get_outgoing_relations(entity, exclude_immutables=True)[source]

Retrieve all relations where the specified entity is the source (obj_from).

This method finds all entity relations in the feed where the given entity is the source or origin of the relationship. Only fully resolved relations are considered to ensure data consistency.

Parameters:
  • entity (EntityTypes) – The entity to find outgoing relations for. Must be an instance of Entity.

  • exclude_immutables (bool) – If True, exclude immutable relations.

Returns:

A dictionary mapping relation IDs to EntityRelation objects where the entity is the source (obj_from).

Return type:

Dict[str, EntityRelation]

get_relations(entity, exclude_immutables=True)[source]

Retrieve all relations (both incoming and outgoing) for the specified entity.

This method combines the results of get_incoming_relations() and get_outgoing_relations() to provide a complete view of all relationships involving the specified entity, regardless of direction.

Parameters:
  • entity (EntityTypes) – The entity to find all relations for. Must be an instance of Entity.

  • exclude_immutables (bool) – If True, exclude immutable relations.

Returns:

A dictionary mapping relation IDs to EntityRelation objects where the entity is either the source (obj_from) or target (obj_to).

Return type:

Dict[str, EntityRelation]

filter(maximum_tlp_level, include_relations=True, include_cases=True, exclude_entity_types=None)[source]

Filter the feed based on TLP (Traffic Light Protocol) level and optionally include relations and cases.

This method creates a new ColanderFeed containing only entities whose TLP level is below the specified maximum threshold. It can optionally include relations between filtered entities and cases associated with the filtered entities.

Parameters:
  • maximum_tlp_level (TlpPapLevel) – The maximum TLP level threshold. Only entities with TLP levels strictly below this value will be included.

  • include_relations (bool, optional) – If True, includes relations where both source and target entities are present in the filtered feed. Defaults to True.

  • include_cases (bool, optional) – If True, includes cases associated with the filtered entities. Defaults to True.

  • exclude_entity_types (Optional[List[EntityTypes]], optional) – If provided, entities of these types are excluded.

Returns:

A new filtered feed containing entities, relations, and cases that meet the specified criteria.

Return type:

ColanderFeed

class colander_data_converter.base.models.ColanderRepository(*args, **kwargs)[source]

Bases: object

Singleton repository for managing and storing Case, Entity, and EntityRelation objects.

This class provides centralized storage and reference management for all model instances, supporting insertion, lookup, and reference resolution/unlinking.

__init__()[source]

Initializes the repository with empty dictionaries for cases, entities, and relations.

__lshift__(other)[source]

Inserts an object into the appropriate repository dictionary.

Parameters:

other (Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator='colander_internal_type')] | Case) – The object (Entity, EntityRelation, or Case) to insert.

__rshift__(other)[source]

Retrieves an object by its identifier from entities, relations, or cases.

Parameters:

other (str | Annotated[UUID, UuidVersion(uuid_version=4)]) – The string or UUID identifier to look up.

Returns:

The found object or the identifier if not found.

Return type:

Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator=’colander_internal_type’)] | EntityRelation | Case | str | Annotated[UUID, UuidVersion(uuid_version=4)]

clear()[source]
resolve_references()[source]

Resolves all UUID references in entities, relations, and cases to their corresponding objects.

Unlinks all object references in entities, relations, and cases by replacing them with UUIDs.

cases: Dict[str, Case]
entities: Dict[str, Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator='colander_internal_type')]]
relations: Dict[str, EntityRelation]
class colander_data_converter.base.models.ColanderType[source]

Bases: BaseModel

Base class for all Colander model data_types, providing common functionality.

This class extends Pydantic’s BaseModel and is intended to be subclassed by all model entities. It includes methods for linking and unlinking object references, resolving type hints, and extracting subclass information.

Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

model_post_init(_ColanderType__context)[source]

Executes post-initialization logic for the model, ensuring the repository registers the current subclass instance.

Parameters:

__context (Any) – Additional context provided for post-initialization handling.

Unlinks object references by replacing them with their respective UUIDs.

This method updates the model fields of the class instance where fields annotated as ObjectReference or List[ObjectReference] exist. It replaces the references (of type objects) with their UUIDs if they exist.

For fields of type ObjectReference, the method retrieves the field’s value and replaces it with its id (UUID) if the current value is not already a UUID.

For fields of type List[ObjectReference], the method iterates through the list and replaces each object reference with its id (UUID) if the current value is not already a UUID. The field value is updated only if at least one replacement occurs.

Raises:

AttributeError – If the class instance does not have the expected field or attribute.

resolve_references(strict=False)[source]

Resolves references for the fields in the object’s model.

Fields annotated with ObjectReference or List[ObjectReference] are processed to fetch and replace their UUID references with respective entities using the Repository.

This method updates the object in-place.

Parameters:

strict – If True, raises a ValueError when a UUID reference cannot be resolved. If False, unresolved references remain as UUIDs.

Raises:

ValueError – If strict is True and a UUID reference cannot be resolved.

is_fully_resolved()[source]
Return type:

bool

classmethod subclasses()[source]

Generates a dictionary containing all subclasses of the current class.

This method collects all the direct subclasses of the current class and maps their names (converted to lowercase) to the class itself. It is primarily useful for organizing and accessing class hierarchies dynamically.

Returns:

A dictionary where the keys are the lowercase names of the subclasses, and the values are the subclass data_types themselves.

Return type:

Dict[str, type[‘EntityTypes’]]

classmethod resolve_type(content_type)[source]

Resolves a specific type of entity definition based on the provided content type by matching it against the available subclasses of the class. This utility ensures that the given content type is valid and matches one of the registered subclasses.

Parameters:

content_type (str) – A string representing the type of content to be resolved. Must match the name of a subclass (in lowercase) of the current class.

Returns:

The resolved class type corresponding to the provided content type.

Return type:

type[‘EntityTypes’]

classmethod extract_type_hints(obj)[source]

Extracts type hints from a given dictionary based on specific keys.

This class method attempts to retrieve type hints from a dictionary using a specific key (“colander_internal_type”) or nested keys (“super_type” and its “short_name” value). If the dictionary does not match the expected structure or the keys are not available, a ValueError is raised.

Parameters:

obj (dict) – The dictionary from which type hints need to be extracted.

Returns:

A string representing the extracted type hint.

Return type:

str

Raises:

ValueError – If the type hint cannot be extracted from the provided dictionary.

property super_type: CommonEntitySuperType
get_super_type()[source]
Return type:

CommonEntitySuperType

class colander_data_converter.base.models.CommonEntitySuperType[source]

Bases: BaseModel

CommonEntitySuperType defines metadata for a super type of entities in the Colander data model.

This class is used to represent high-level categories of entities (such as Actor, Artifact, Device, etc.) and provides fields for the short name, display name, associated types, and the Python class implementing the entity.

Fields:
field short_name: str [Required]

A short name for the model type.

Constraints:
  • max_length = 32

field name: str [Required]

The name of the model type.

Constraints:
  • max_length = 512

field types: List[object] | None = None

Optional reference to the enum or collection of supported types.

field model_class: Any = None

The Python class associated with this super type (Observable…).

field type_class: Any = None

The Python class associated with the entity type (ObservableType…).

field default_type: Any = None

The default entity type (GENERIC…).

type_by_short_name(short_name)[source]
class colander_data_converter.base.models.CommonEntitySuperTypes(*values)[source]

Bases: Enum

CommonEntitySuperTypes is an enumeration of all super types for entities in the Colander data model.

Each member of this enum represents a high-level entity category (such as Actor, Artifact, Device, etc.) and holds a CommonEntitySuperType instance containing metadata and references to the corresponding entity class and its supported types.

This enum is used for type resolution and validation across the model.

Example

>>> super_type = CommonEntitySuperTypes.ACTOR.value
>>> print(super_type.name)
Actor
classmethod by_short_name(short_name)[source]
Return type:

CommonEntitySuperType | None

ACTOR = ACTOR
ARTIFACT = ARTIFACT
DATA_FRAGMENT = DATAFRAGMENT
DETECTION_RULE = DETECTIONRULE
DEVICE = DEVICE
EVENT = EVENT
OBSERVABLE = OBSERVABLE
THREAT = THREAT
class colander_data_converter.base.models.DataFragment[source]

Bases: Entity

DataFragment represents a fragment of data, such as a code snippet, text, or other content.

This class extends the Entity base class and includes additional fields specific to data fragments, such as their type, content, and the artifact from which they were extracted.

Example

>>> data_fragment_type = DataFragmentTypes.CODE.value
>>> artifact = Artifact(
...     name='example_artifact',
...     type=ArtifactTypes.DOCUMENT.value
... )
>>> data_fragment = DataFragment(
...     name='Sample Code',
...     type=data_fragment_type,
...     content='print("Hello, World!")',
...     extracted_from=artifact
... )
>>> print(data_fragment.content)
print("Hello, World!")
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: DataFragmentType [Required]

The type definition for the data fragment.

field content: str [Required]

The content of the data fragment.

field extracted_from: Artifact | None | ObjectReference = None

Reference to the artifact from which this data fragment was extracted.

field colander_internal_type: Literal['datafragment'] = 'datafragment'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.DetectionRule[source]

Bases: Entity

DetectionRule represents a rule used for detecting specific content or logic related to observables or object references.

This class is designed to encapsulate detection rules that can be applied across various systems or platforms to identify patterns or conditions defined by the user.

Example

>>> drt = DetectionRuleTypes.YARA.value
>>> rule = DetectionRule(
...     name='Detect Malicious IP',
...     type=drt,
...     content='rule malicious_ip { condition: true }',
... )
>>> print(rule.name)
Detect Malicious IP
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: DetectionRuleType [Required]

The type definition for the detection rule.

field content: str [Required]

The content or logic of the detection rule.

field targeted_observables: List[Observable] | None | List[ObjectReference] = None

List of observables or references targeted by this detection rule.

field colander_internal_type: Literal['detectionrule'] = 'detectionrule'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.Device[source]

Bases: Entity

Device represents a physical or virtual device in Colander.

This class extends the Entity base class and includes additional fields specific to devices, such as their type, attributes, and the actor operating the device.

Example

>>> device_type = DeviceTypes.MOBILE.value
>>> actor = Actor(name='John Doe', type=ActorTypes.INDIVIDUAL.value)
>>> device = Device(
...     name="John's Phone",
...     type=device_type,
...     operated_by=actor,
...     attributes={'os': 'Android', 'version': '12'}
... )
>>> print(device.name)
John's Phone
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: DeviceType [Required]

The type definition for the device.

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the device.

field operated_by: Actor | None | ObjectReference = None

Reference to the actor operating the device.

field colander_internal_type: Literal['device'] = 'device'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.Entity[source]

Bases: ColanderType, ABC

Entity is an abstract base class representing a core object in the model.

This class provides common fields for all entities, including identifiers, timestamps, descriptive fields, and references to cases. Examples include actors, artifacts, devices, etc.

Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field id: Annotated[UUID, UuidVersion(uuid_version=4)] [Optional]

The unique identifier for the entity.

Constraints:
  • uuid_version = 4

field created_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 541280, tzinfo=datetime.timezone.utc)

The timestamp when the entity was created.

field updated_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 541301, tzinfo=datetime.timezone.utc)

The timestamp when the entity was last updated.

field name: str [Required]

The name of the entity.

Constraints:
  • min_length = 1

  • max_length = 512

field case: Case | None | ObjectReference = None

Reference to the case this entity belongs to.

field description: str | None = None

A description of the entity.

field pap: TlpPapLevel = WHITE

The PAP (Permissible Actions Protocol) level for the entity.

field source_url: str | AnyUrl | None = None

Optional source URL for the entity.

field tlp: TlpPapLevel = WHITE

The TLP (Traffic Light Protocol) level for the entity.

get_type()[source]

Returns the type definition for this entity instance.

This method returns the type definition object (e.g., ObservableType, ActorType, DeviceType).

Returns:

The type definition object for this entity. The specific type depends

on the entity subclass (e.g., Observable returns ObservableType, Actor returns ActorType, etc.).

Return type:

Optional[_EntityType]

get_immutable_relations(mapping=None, default_name=None)[source]

Returns a dictionary of immutable relations derived from the entity’s reference fields.

This method automatically creates EntityRelation objects by inspecting the entity’s fields and identifying those annotated as ObjectReference or List[ObjectReference]. These represent the entity’s connections to other entities in the knowledge graph, forming the basis for graph traversal and relationship analysis.

Immutable relations are derived from the entity’s structure and cannot be modified directly. They represent inherent relationships defined by the entity’s reference fields, such as ‘extracted_from’, ‘operated_by’, ‘associated_threat’, etc.

Parameters:
  • mapping (Dict[str, str], optional) – A dictionary to customize relation names. Keys should be field names, and values should be the desired relation names. If not provided, field names are converted to human-readable format by replacing underscores with spaces. Defaults to None.

  • default_name (str) – If a mapping is provided but no field mapping was found, the relation will be named ‘default_new_name’.

Returns:

A dictionary of EntityRelation objects keyed by their string representation of relation IDs. Each relation represents a connection from this entity to another entity referenced in its fields.

Return type:

Dict[str, “EntityRelation”]

Note

  • The ‘case’ field is explicitly excluded from relation generation as it represents a grouping mechanism rather than a semantic relationship.

  • Only fields with actual values (not None or empty) are processed.

  • Each EntityRelation created has this entity as the source (obj_from) and the referenced entity as the target (obj_to).

class colander_data_converter.base.models.EntityRelation[source]

Bases: ColanderType

EntityRelation represents a relationship between two entities in the model.

This class is used to define and manage relationships between objects, such as associations between observables, devices, or actors.

Example

>>> obs1 = Observable(
...     id=uuid4(),
...     name='1.1.1.1',
...     type=ObservableTypes.IPV4.value
... )
>>> obs2 = Observable(
...     id=uuid4(),
...     name='8.8.8.8',
...     type=ObservableTypes.IPV4.value
... )
>>> relation = EntityRelation(
...     id=uuid4(),
...     name='connection',
...     obj_from=obs1,
...     obj_to=obs2
... )
>>> print(relation.name)
connection
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field id: Annotated[UUID, UuidVersion(uuid_version=4)] [Optional]

The unique identifier for the entity relation.

Constraints:
  • uuid_version = 4

field created_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 542536, tzinfo=datetime.timezone.utc)

The timestamp when the entity relation was created.

field updated_at: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 542557, tzinfo=datetime.timezone.utc)

The timestamp when the entity relation was last updated.

field name: str [Required]

The name of the entity relation.

Constraints:
  • min_length = 1

  • max_length = 512

field case: Case | None | ObjectReference = None

Reference to the case this relation belongs to.

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the relation.

field obj_from: Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator='colander_internal_type')] | ObjectReference [Required]

The source entity or reference in the relation.

field obj_to: Annotated[Actor | Artifact | DataFragment | Observable | DetectionRule | Device | Event | Threat, FieldInfo(annotation=NoneType, required=True, discriminator='colander_internal_type')] | ObjectReference [Required]

The target entity or reference in the relation.

class colander_data_converter.base.models.Event[source]

Bases: Entity

Event represents an occurrence or activity observed within a system, such as a detection, alert, or log entry.

This class extends the Entity base class and includes additional fields specific to events, such as timestamps, count, involved observables, and references to related entities.

Example

>>> et = EventTypes.HIT.value
>>> obs_type = ObservableTypes.IPV4.value
>>> obs = Observable(
...     id=uuid4(),
...     name='8.8.8.8',
...     type=obs_type
... )
>>> event = Event(
...     name='Suspicious Connection',
...     type=et,
...     first_seen=datetime(2024, 6, 1, 12, 0, tzinfo=UTC),
...     last_seen=datetime(2024, 6, 1, 12, 5, tzinfo=UTC),
...     involved_observables=[obs]
... )
>>> print(event.name)
Suspicious Connection
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
Validators:
  • _check_dates » all fields

field type: EventType [Required]

The type definition for the event.

Validated by:
  • _check_dates

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the event.

Validated by:
  • _check_dates

field first_seen: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 550713, tzinfo=datetime.timezone.utc)

The timestamp when the event was first observed.

Validated by:
  • _check_dates

field last_seen: datetime = datetime.datetime(2025, 8, 10, 18, 48, 34, 550715, tzinfo=datetime.timezone.utc)

The timestamp when the event was last observed.

Validated by:
  • _check_dates

field count: Annotated[int, Gt(gt=0)] = 1

The number of times this event was observed.

Constraints:
  • gt = 0

Validated by:
  • _check_dates

field extracted_from: Artifact | None | ObjectReference = None

Reference to the artifact from which this event was extracted.

Validated by:
  • _check_dates

field observed_on: Device | None | ObjectReference = None

Reference to the device on which this event was observed.

Validated by:
  • _check_dates

field detected_by: DetectionRule | None | ObjectReference = None

Reference to the detection rule that detected this event.

Validated by:
  • _check_dates

field attributed_to: Actor | None | ObjectReference = None

Reference to the actor attributed to this event.

Validated by:
  • _check_dates

field target: Actor | None | ObjectReference = None

Reference to the actor targeted during this event.

Validated by:
  • _check_dates

field involved_observables: List[Observable] | List[ObjectReference] = []

List of observables or references involved in this event.

Validated by:
  • _check_dates

field colander_internal_type: Literal['event'] = 'event'

Internal type discriminator for (de)serialization.

Validated by:
  • _check_dates

class colander_data_converter.base.models.Observable[source]

Bases: Entity

Observable represents an entity that can be observed or detected within the system.

This class extends the Entity base class and includes additional fields specific to observables, such as classification, raw value, extraction source, associated threat, and operator.

Example

>>> ot = ObservableTypes.IPV4.value
>>> obs = Observable(
...     name='1.2.3.4',
...     type=ot,
...     classification='malicious',
...     raw_value='1.2.3.4',
...     attributes={'asn': 'AS123'}
... )
>>> print(obs.name)
1.2.3.4
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: ObservableType [Required]

The type definition for the observable.

field attributes: Dict[str, str] | None = None

Dictionary of additional attributes for the observable.

field classification: str | None = None

Optional classification label for the observable.

Constraints:
  • max_length = 512

field raw_value: str | None = None

The raw value associated with the observable.

field extracted_from: Artifact | None | ObjectReference = None

Reference to the artifact from which this observable was extracted.

field associated_threat: Threat | None | ObjectReference = None

Reference to an associated threat.

field operated_by: Actor | None | ObjectReference = None

Reference to the actor operating this observable.

field colander_internal_type: Literal['observable'] = 'observable'

Internal type discriminator for (de)serialization.

class colander_data_converter.base.models.Threat[source]

Bases: Entity

Threat represents a threat entity, such as a malware family, campaign, or adversary.

This class extends the Entity base class and includes a type field for threat classification.

Example

>>> threat_type = ThreatTypes.TROJAN.value
>>> threat = Threat(
...     name='Emotet',
...     type=threat_type
... )
>>> print(threat.name)
Emotet
Config:
  • str_strip_whitespace: bool = True

  • arbitrary_types_allowed: bool = True

Fields:
field type: ThreatType [Required]

The type definition for the threat.

field colander_internal_type: Literal['threat'] = 'threat'

Internal type discriminator for (de)serialization.

colander_data_converter.base.models.get_id(obj)[source]

Extracts a UUID4 identifier from the given object.

Parameters:

obj (Any) – The object to extract the UUID from. Can be a string, UUID, or an object with an ‘id’ attribute.

Returns:

The extracted UUID4 if available, otherwise None.

Return type:

Optional[UUID4]