Skip to content
This repository was archived by the owner on Dec 5, 2025. It is now read-only.

Commit b249661

Browse files
authored
[doc] Rha/add sphinx doc (#87)
* Add docstrings to api * Add more docstrings for api jobs * More docstrings * More docstring update
1 parent 6bc9897 commit b249661

File tree

4 files changed

+180
-20
lines changed

4 files changed

+180
-20
lines changed

pycti/connector/opencti_connector.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ class ConnectorType(Enum):
1919

2020

2121
class OpenCTIConnector:
22+
"""Main class for OpenCTI connector
23+
24+
:param connector_id: id for the connector (valid uuid4)
25+
:type connector_id: str
26+
:param connector_name: name for the connector
27+
:type connector_name: str
28+
:param connector_type: valid OpenCTI connector type (see `ConnectorType`)
29+
:type connector_type: str
30+
:param scope: connector scope
31+
:type scope: str
32+
:raises ValueError: if the connector type is not valid
33+
"""
34+
2235
def __init__(
2336
self, connector_id: str, connector_name: str, connector_type: str, scope: str
2437
):
@@ -29,7 +42,12 @@ def __init__(
2942
raise ValueError("Invalid connector type: " + connector_type)
3043
self.scope = scope.split(",")
3144

32-
def to_input(self):
45+
def to_input(self) -> dict:
46+
"""connector input to use in API query
47+
48+
:return: dict with connector data
49+
:rtype: dict
50+
"""
3351
return {
3452
"input": {
3553
"id": self.id,

pycti/connector/opencti_connector_helper.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,15 @@ def stix2_get_embedded_objects(self, item) -> dict:
469469
"created_by_ref": created_by_ref,
470470
}
471471

472-
def stix2_get_entity_objects(self, entity):
472+
def stix2_get_entity_objects(self, entity) -> list:
473+
"""process a stix2 entity
474+
475+
:param entity: valid stix2 entity
476+
:type entity:
477+
:return: entity objects as list
478+
:rtype: list
479+
"""
480+
473481
items = [entity]
474482
# Get embedded objects
475483
embedded_objects = self.stix2_get_embedded_objects(entity)
@@ -482,7 +490,15 @@ def stix2_get_entity_objects(self, entity):
482490

483491
return items
484492

485-
def stix2_get_relationship_objects(self, relationship):
493+
def stix2_get_relationship_objects(self, relationship) -> list:
494+
"""get a list of relations for a stix2 relationship object
495+
496+
:param relationship: valid stix2 relationship
497+
:type relationship:
498+
:return: list of relations objects
499+
:rtype: list
500+
"""
501+
486502
items = [relationship]
487503
# Get source ref
488504
if relationship["source_ref"] in self.cache_index:
@@ -503,7 +519,15 @@ def stix2_get_relationship_objects(self, relationship):
503519

504520
return items
505521

506-
def stix2_get_report_objects(self, report):
522+
def stix2_get_report_objects(self, report) -> list:
523+
"""get a list of items for a stix2 report object
524+
525+
:param report: valid stix2 report object
526+
:type report:
527+
:return: list of items for a stix2 report object
528+
:rtype: list
529+
"""
530+
507531
items = [report]
508532
# Add all object refs
509533
for object_ref in report["object_refs"]:
@@ -516,7 +540,15 @@ def stix2_get_report_objects(self, report):
516540
return items
517541

518542
@staticmethod
519-
def stix2_deduplicate_objects(items):
543+
def stix2_deduplicate_objects(items) -> list:
544+
"""deduplicate stix2 items
545+
546+
:param items: valid stix2 items
547+
:type items:
548+
:return: de-duplicated list of items
549+
:rtype: list
550+
"""
551+
520552
ids = []
521553
final_items = []
522554
for item in items:
@@ -527,6 +559,14 @@ def stix2_deduplicate_objects(items):
527559

528560
@staticmethod
529561
def stix2_create_bundle(items):
562+
"""create a stix2 bundle with items
563+
564+
:param items: valid stix2 items
565+
:type items:
566+
:return: JSON of the stix2 bundle
567+
:rtype:
568+
"""
569+
530570
bundle = {
531571
"type": "bundle",
532572
"id": "bundle--" + str(uuid.uuid4()),
@@ -536,7 +576,17 @@ def stix2_create_bundle(items):
536576
return json.dumps(bundle)
537577

538578
@staticmethod
539-
def check_max_tlp(tlp, max_tlp):
579+
def check_max_tlp(tlp, max_tlp) -> list:
580+
"""check the allowed TLP levels for a TLP string
581+
582+
:param tlp: string for TLP level to check
583+
:type tlp: str
584+
:param max_tlp: the highest allowed TLP level
585+
:type max_tlp: str
586+
:return: list of allowed TLP levels
587+
:rtype: list
588+
"""
589+
540590
allowed_tlps = ["TLP:WHITE"]
541591
if max_tlp == "TLP:RED":
542592
allowed_tlps = ["TLP:WHITE", "TLP:GREEN", "TLP:AMBER", "TLP:RED"]

pycti/utils/constants.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
class ObservableTypes(Enum):
88
"""These are the possible values for OpenCTI's observable types.
9-
Use in conjuction with the STIX custom property 'x_opencti_observable_type'.
9+
10+
Use in conjunction with the STIX custom property `x_opencti_observable_type`.
11+
1012
ref: https://github.com/OpenCTI-Platform/opencti/blob/8854c2576dc17da9da54e54b116779bd2131617c/opencti-front/src/private/components/report/ReportAddObservable.js
13+
1114
NOTE: should this be a mapping between the stix2 SDO objects (i.e. stix2/v20/sdo.py)?
1215
"""
1316

@@ -69,8 +72,7 @@ def has_value(cls, value):
6972

7073

7174
class CustomProperties:
72-
"""These are the custom properies used by OpenCTI.
73-
75+
"""These are the custom properties used by OpenCTI.
7476
"""
7577

7678
# internal id used by OpenCTI - this will be auto generated

pycti/utils/opencti_stix2.py

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,26 @@ def unknown_type(self, stix_object):
4545
'Unknown object type "' + stix_object["type"] + '", doing nothing...',
4646
)
4747

48-
def convert_markdown(self, text):
48+
def convert_markdown(self, text) -> str:
49+
"""converts input text to markdown style code annotation
50+
51+
:param text: input text
52+
:type text: str
53+
:return: sanitized text with markdown style code annotation
54+
:rtype: str
55+
"""
56+
4957
return text.replace("<code>", "`").replace("</code>", "`")
5058

5159
def format_date(self, date):
60+
"""converts multiple input date formats to OpenCTI style dates
61+
62+
:param date: input date
63+
:type date:
64+
:return: OpenCTI style date
65+
:rtype: datetime
66+
"""
67+
5268
if isinstance(date, datetime.date):
5369
return date.isoformat(timespec="milliseconds").replace("+00:00", "Z")
5470
if date is not None:
@@ -64,15 +80,33 @@ def format_date(self, date):
6480
.replace("+00:00", "Z")
6581
)
6682

67-
def filter_objects(self, uuids, objects):
83+
def filter_objects(self, uuids: list, objects: list) -> list:
84+
"""filters objects based on UUIDs
85+
86+
:param uuids: list of UUIDs
87+
:type uuids: list
88+
:param objects: list of objects to filter
89+
:type objects: list
90+
:return: list of filtered objects
91+
:rtype: list
92+
"""
93+
6894
result = []
6995
if objects is not None:
70-
for object in objects:
71-
if "id" in object and object["id"] not in uuids:
72-
result.append(object)
96+
for item in objects:
97+
if "id" in item and item["id"] not in uuids:
98+
result.append(item)
7399
return result
74100

75-
def pick_aliases(self, stix_object):
101+
def pick_aliases(self, stix_object) -> list:
102+
"""check stix2 object for multiple aliases and return a list
103+
104+
:param stix_object: valid stix2 object
105+
:type stix_object:
106+
:return: list of aliases
107+
:rtype: list
108+
"""
109+
76110
# Add aliases
77111
if CustomProperties.ALIASES in stix_object:
78112
return stix_object[CustomProperties.ALIASES]
@@ -85,8 +119,18 @@ def pick_aliases(self, stix_object):
85119
return None
86120

87121
def check_max_marking_definition(
88-
self, max_marking_definition_entity, entity_marking_definitions
89-
):
122+
self, max_marking_definition_entity: str, entity_marking_definitions: list
123+
) -> bool:
124+
"""checks if a list of marking definitions conforms with a given max level
125+
126+
:param max_marking_definition_entity: the maximum allowed marking definition level
127+
:type max_marking_definition_entity: str, optional
128+
:param entity_marking_definitions: list of entities to check
129+
:type entity_marking_definitions: list
130+
:return: `True` if the list conforms with max marking definition
131+
:rtype: bool
132+
"""
133+
90134
# Max is not set, return True
91135
if max_marking_definition_entity is None:
92136
return True
@@ -111,7 +155,19 @@ def check_max_marking_definition(
111155
return True
112156
return False
113157

114-
def import_bundle_from_file(self, file_path, update=False, types=None):
158+
def import_bundle_from_file(self, file_path: str, update=False, types=None) -> List:
159+
"""import a stix2 bundle from a file
160+
161+
:param file_path: valid path to the file
162+
:type file_path: str
163+
:param update: whether to updated data in the database, defaults to False
164+
:type update: bool, optional
165+
:param types: list of stix2 types, defaults to None
166+
:type types: list, optional
167+
:return: list of imported stix2 objects
168+
:rtype: List
169+
"""
170+
115171
if types is None:
116172
types = []
117173
if not os.path.isfile(file_path):
@@ -124,12 +180,34 @@ def import_bundle_from_file(self, file_path, update=False, types=None):
124180
return self.import_bundle(data, update, types)
125181

126182
def import_bundle_from_json(self, json_data, update=False, types=None) -> List:
183+
"""import a stix2 bundle from JSON data
184+
185+
:param json_data: JSON data
186+
:type json_data:
187+
:param update: whether to updated data in the database, defaults to False
188+
:type update: bool, optional
189+
:param types: list of stix2 types, defaults to None
190+
:type types: list, optional
191+
:return: list of imported stix2 objects
192+
:rtype: List
193+
"""
194+
127195
if types is None:
128196
types = []
129197
data = json.loads(json_data)
130198
return self.import_bundle(data, update, types)
131199

132-
def extract_embedded_relationships(self, stix_object, types=None):
200+
def extract_embedded_relationships(self, stix_object, types=None) -> dict:
201+
"""extracts embedded relationship objects from a stix2 entity
202+
203+
:param stix_object: valid stix2 object
204+
:type stix_object:
205+
:param types: list of stix2 types, defaults to None
206+
:type types: list, optional
207+
:return: embedded relationships as dict
208+
:rtype: dict
209+
"""
210+
133211
# Created By Ref
134212
created_by_ref_id = None
135213
if "created_by_ref" in stix_object:
@@ -381,7 +459,19 @@ def extract_embedded_relationships(self, stix_object, types=None):
381459
"reports": reports,
382460
}
383461

384-
def import_object(self, stix_object, update=False, types=None):
462+
def import_object(self, stix_object, update=False, types=None) -> list:
463+
"""import a stix2 object
464+
465+
:param stix_object: valid stix2 object
466+
:type stix_object:
467+
:param update: whether to updated data in the database, defaults to False
468+
:type update: bool, optional
469+
:param types: list of stix2 types, defaults to None
470+
:type types: list, optional
471+
:return: list of imported stix2 objects
472+
:rtype: list
473+
"""
474+
385475
self.opencti.log(
386476
"info",
387477
"Importing a " + stix_object["type"] + " (id: " + stix_object["id"] + ")",

0 commit comments

Comments
 (0)