pycti 6.5.1__py3-none-any.whl → 6.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pycti might be problematic. Click here for more details.

pycti/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "6.5.1"
2
+ __version__ = "6.5.2"
3
3
 
4
4
  from .api.opencti_api_client import OpenCTIApiClient
5
5
  from .api.opencti_api_connector import OpenCTIApiConnector
@@ -3,7 +3,7 @@ import base64
3
3
  import datetime
4
4
  import io
5
5
  import json
6
- from typing import Union
6
+ from typing import Dict, Tuple, Union
7
7
 
8
8
  import magic
9
9
  import requests
@@ -83,13 +83,13 @@ class OpenCTIApiClient:
83
83
  :param log_level: log level for the client
84
84
  :type log_level: str, optional
85
85
  :param ssl_verify: Requiring the requests to verify the TLS certificate at the server.
86
- :type ssl_verify: bool, optional
86
+ :type ssl_verify: bool, str, optional
87
87
  :param proxies:
88
88
  :type proxies: dict, optional, The proxy configuration, would have `http` and `https` attributes. Defaults to {}
89
89
  ```
90
90
  proxies: {
91
- "http: "http://my_proxy:8080"
92
- "https: "http://my_proxy:8080"
91
+ "http": "http://my_proxy:8080"
92
+ "https": "http://my_proxy:8080"
93
93
  }
94
94
  ```
95
95
  :param json_logging: format the logs as json if set to True
@@ -102,14 +102,14 @@ class OpenCTIApiClient:
102
102
 
103
103
  def __init__(
104
104
  self,
105
- url,
106
- token,
105
+ url: str,
106
+ token: str,
107
107
  log_level="info",
108
- ssl_verify=False,
109
- proxies=None,
108
+ ssl_verify: Union[bool, str] = False,
109
+ proxies: Union[Dict[str, str], None] = None,
110
110
  json_logging=False,
111
111
  bundle_send_to_queue=True,
112
- cert=None,
112
+ cert: Union[str, Tuple[str, str], None] = None,
113
113
  auth=None,
114
114
  perform_health_check=True,
115
115
  ):
@@ -712,12 +712,13 @@ class OpenCTIApiClient:
712
712
  data = kwargs.get("data", None)
713
713
  mime_type = kwargs.get("mime_type", "text/plain")
714
714
  entity_id = kwargs.get("entity_id", None)
715
+ file_markings = kwargs.get("file_markings", [])
715
716
 
716
717
  if file_name is not None:
717
718
  self.app_logger.info("Uploading a file.")
718
719
  query = """
719
- mutation UploadPending($file: Upload!, $entityId: String) {
720
- uploadPending(file: $file, entityId: $entityId) {
720
+ mutation UploadPending($file: Upload!, $entityId: String, $file_markings: [String!]) {
721
+ uploadPending(file: $file, entityId: $entityId, file_markings: $file_markings) {
721
722
  id
722
723
  name
723
724
  }
@@ -731,7 +732,11 @@ class OpenCTIApiClient:
731
732
  mime_type = magic.from_file(file_name, mime=True)
732
733
  return self.query(
733
734
  query,
734
- {"file": (File(file_name, data, mime_type)), "entityId": entity_id},
735
+ {
736
+ "file": (File(file_name, data, mime_type)),
737
+ "entityId": entity_id,
738
+ "file_markings": file_markings,
739
+ },
735
740
  )
736
741
  else:
737
742
  self.app_logger.error("[upload] Missing parameter: file_name")
@@ -769,6 +769,9 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
769
769
  def __init__(self, config: Dict, playbook_compatible=False) -> None:
770
770
  sys.excepthook = killProgramHook
771
771
 
772
+ # Cache
773
+ self.stream_collections = {}
774
+
772
775
  # Load API config
773
776
  self.config = config
774
777
  self.opencti_url = get_config_variable(
@@ -1063,6 +1066,9 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1063
1066
  "stream_live": True,
1064
1067
  "stream_public": False,
1065
1068
  }
1069
+ # Get from cache
1070
+ elif self.connect_live_stream_id in self.stream_collections:
1071
+ return self.stream_collections[self.connect_live_stream_id]
1066
1072
  else:
1067
1073
  query = """
1068
1074
  query StreamCollection($id: String!) {
@@ -1076,6 +1082,10 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1076
1082
  }
1077
1083
  """
1078
1084
  result = self.api.query(query, {"id": self.connect_live_stream_id})
1085
+ # Put in cache
1086
+ self.stream_collections[self.connect_live_stream_id] = result["data"][
1087
+ "streamCollection"
1088
+ ]
1079
1089
  return result["data"]["streamCollection"]
1080
1090
  else:
1081
1091
  raise ValueError("This connector is not connected to any stream")
@@ -1581,6 +1591,7 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1581
1591
  event_version = kwargs.get("event_version", None)
1582
1592
  bypass_validation = kwargs.get("bypass_validation", False)
1583
1593
  entity_id = kwargs.get("entity_id", None)
1594
+ file_markings = kwargs.get("file_markings", None)
1584
1595
  file_name = kwargs.get("file_name", None)
1585
1596
  bundle_send_to_queue = kwargs.get("send_to_queue", self.bundle_send_to_queue)
1586
1597
  cleanup_inconsistent_bundle = kwargs.get("cleanup_inconsistent_bundle", False)
@@ -1648,6 +1659,7 @@ class OpenCTIConnectorHelper: # pylint: disable=too-many-public-methods
1648
1659
  data=bundle,
1649
1660
  mime_type="application/json",
1650
1661
  entity_id=entity_id,
1662
+ file_markings=file_markings,
1651
1663
  )
1652
1664
  return []
1653
1665
  elif validation_mode == "draft" and not draft_id:
@@ -1,5 +1,5 @@
1
- import datetime
2
1
  import logging
2
+ from datetime import datetime, timezone
3
3
 
4
4
  from pythonjsonlogger import jsonlogger
5
5
 
@@ -9,8 +9,8 @@ class CustomJsonFormatter(jsonlogger.JsonFormatter):
9
9
  super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
10
10
  if not log_record.get("timestamp"):
11
11
  # This doesn't use record.created, so it is slightly off
12
- now = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%fZ")
13
- log_record["timestamp"] = now
12
+ now = datetime.now(tz=timezone.utc)
13
+ log_record["timestamp"] = now.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
14
14
  if log_record.get("level"):
15
15
  log_record["level"] = log_record["level"].upper()
16
16
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pycti
3
- Version: 6.5.1
3
+ Version: 6.5.2
4
4
  Summary: Python API client for OpenCTI.
5
5
  Home-page: https://github.com/OpenCTI-Platform/client-python
6
6
  Author: Filigran
@@ -40,8 +40,8 @@ Requires-Dist: stix2~=3.0.1
40
40
  Provides-Extra: dev
41
41
  Requires-Dist: black~=24.4.0; extra == "dev"
42
42
  Requires-Dist: build~=1.2.1; extra == "dev"
43
- Requires-Dist: isort~=5.13.0; extra == "dev"
44
- Requires-Dist: types-pytz~=2024.2.0.20241221; extra == "dev"
43
+ Requires-Dist: isort~=6.0.0; extra == "dev"
44
+ Requires-Dist: types-pytz~=2025.1.0.20250204; extra == "dev"
45
45
  Requires-Dist: pre-commit~=3.8.0; extra == "dev"
46
46
  Requires-Dist: pytest-cases~=3.8.0; extra == "dev"
47
47
  Requires-Dist: pytest-cov~=5.0.0; extra == "dev"
@@ -1,12 +1,12 @@
1
- pycti/__init__.py,sha256=EDjdNBXpv2xU_AQbYOiHSi_MofEgIVd8wu2Da6VISF8,5218
1
+ pycti/__init__.py,sha256=vuINZwJahwqFmxz7ZhxCxVAk8eEKHZO6_pveLWsEQ3U,5218
2
2
  pycti/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- pycti/api/opencti_api_client.py,sha256=OBXRNBbkYsbgqjxeY5iltHXIDeWqpFN3-SKsinkr66U,32402
3
+ pycti/api/opencti_api_client.py,sha256=6TKvtgAk0iYQL2RaLTUV6cxCBefEgwmlL_iVHgzf_ow,32745
4
4
  pycti/api/opencti_api_connector.py,sha256=ubM_zPjTD8L33TEugCQgf_YF9zugDFg_7FgNubGlwJw,5447
5
5
  pycti/api/opencti_api_playbook.py,sha256=456We78vESukfSOi_CctfZ9dbBJEi76EHClRc2f21Js,1628
6
6
  pycti/api/opencti_api_work.py,sha256=qIRJMCfyC9odXf7LMRg9ImYizqF2WHUOU7Ty5IUFGg8,8351
7
7
  pycti/connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  pycti/connector/opencti_connector.py,sha256=5oVvS27KWhzRiofJAeQPDtba-EP83FziSistyEd5l-U,2561
9
- pycti/connector/opencti_connector_helper.py,sha256=Az_scgGMBsZ5_m6_DNsKL84pWgJbD_Lksa2CkWkWipg,80772
9
+ pycti/connector/opencti_connector_helper.py,sha256=ee8Ej43Ox9W7G44PEfHNGZuU_NmBVNl7dE3V3BzE4sE,81286
10
10
  pycti/connector/opencti_metric_handler.py,sha256=4jXHeJflomtHjuQ_YU0b36TG7o26vOWbY_jvU8Ezobs,3725
11
11
  pycti/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  pycti/entities/opencti_attack_pattern.py,sha256=rj3o2bFCoXniLmD9Ithi09S9Us8ab1G-GFLgqS8jll0,22237
@@ -61,14 +61,14 @@ pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_deprecated.py
61
61
  pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py,sha256=MN56CW8RWZwB0Pr8UiHZy_4nSzbgFbwdhSFKpsZ_d1Y,11293
62
62
  pycti/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
63
  pycti/utils/constants.py,sha256=ZgOVxY5bnrHiNvPgOfZLWk16sSDnaE_tg8JVjZpw24Q,11831
64
- pycti/utils/opencti_logger.py,sha256=0dvB75V0SuPFGxL539dAQrxTt1N5Acx0A3Ogwl5WMJ8,2199
64
+ pycti/utils/opencti_logger.py,sha256=BHNy9fJuTUTn_JEYSCmyvVwd6y-9ZJKxO40mY4iZ0bc,2226
65
65
  pycti/utils/opencti_stix2.py,sha256=pUx1Oglb1EnREheMzmJBrmRS17vGnZzF8PCmB-pjNM0,117680
66
66
  pycti/utils/opencti_stix2_identifier.py,sha256=k8L1z4q1xdCBfxqUba4YS_kT-MmbJFxYh0RvfGOmrOs,837
67
67
  pycti/utils/opencti_stix2_splitter.py,sha256=etnAWMDzNi2JCovSUJ5Td-XLVdzgKRdsV1XfpXOGols,11070
68
68
  pycti/utils/opencti_stix2_update.py,sha256=CnMyqkeVA0jgyxEcgqna8sABU4YPMjkEJ228GVurIn4,14658
69
69
  pycti/utils/opencti_stix2_utils.py,sha256=xgBZzm7HC76rLQYwTKkaUd_w9jJnVMoryHx7KDDIB_g,5065
70
- pycti-6.5.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
- pycti-6.5.1.dist-info/METADATA,sha256=MAlkjZwkBgaOT5zmyFolpyg3y_eYxFlIx-7ngO-l9Dk,5419
72
- pycti-6.5.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
73
- pycti-6.5.1.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
74
- pycti-6.5.1.dist-info/RECORD,,
70
+ pycti-6.5.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
+ pycti-6.5.2.dist-info/METADATA,sha256=t7YyxQyOxdyFCqF7DF_iWCG9XK-Hj8vMWuB9vHvrRlQ,5418
72
+ pycti-6.5.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
73
+ pycti-6.5.2.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
74
+ pycti-6.5.2.dist-info/RECORD,,
File without changes
File without changes