howler-api 2.13.0.dev345__py3-none-any.whl → 3.0.0.dev349__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.
@@ -207,6 +207,7 @@ class ESCollection(Generic[ModelType]):
207
207
  "script_fields": [],
208
208
  }
209
209
  IGNORE_ENSURE_COLLECTION = False
210
+ ENSURE_COLLECTION_WARNED = False
210
211
 
211
212
  def __init__(self, datastore: ESStore, name, model_class=None, validate=True, max_attempts=10):
212
213
  self.replicas = int(
@@ -227,9 +228,10 @@ class ESCollection(Generic[ModelType]):
227
228
 
228
229
  if not ESCollection.IGNORE_ENSURE_COLLECTION:
229
230
  self._ensure_collection()
230
- elif "pytest" not in sys.modules:
231
+ elif "pytest" not in sys.modules and not ESCollection.ENSURE_COLLECTION_WARNED:
231
232
  logger.warning("Skipping ensure collection! This is dangerous. Waiting five seconds before continuing.")
232
233
  time.sleep(5)
234
+ ESCollection.ENSURE_COLLECTION_WARNED = True
233
235
 
234
236
  self.stored_fields = {}
235
237
  if model_class:
@@ -21,6 +21,7 @@ from howler.odm import (
21
21
  Integer,
22
22
  Json,
23
23
  Keyword,
24
+ Long,
24
25
  LowerKeyword,
25
26
  PhoneNumber,
26
27
  Platform,
@@ -37,6 +38,7 @@ BASE_TYPE_MAPPING = {
37
38
  Keyword: "keyword",
38
39
  Boolean: "boolean",
39
40
  Integer: "integer",
41
+ Long: "long",
40
42
  Float: "float",
41
43
  Date: "date",
42
44
  Text: "text",
@@ -15,6 +15,7 @@ from howler.odm import (
15
15
  Json,
16
16
  Keyword,
17
17
  List,
18
+ Long,
18
19
  Mapping,
19
20
  Optional,
20
21
  Text,
@@ -57,7 +58,7 @@ def build_mapping(field_data, prefix=None, allow_refuse_implicit=True):
57
58
  }
58
59
  )
59
60
 
60
- elif isinstance(field, (Boolean, Integer, Float, Text)):
61
+ elif isinstance(field, (Boolean, Integer, Float, Text, Long)):
61
62
  mappings[name.strip(".")] = set_mapping(field, {"type": TYPE_MAPPING[field.__class__.__name__]})
62
63
 
63
64
  elif field.__class__ in ANALYZER_MAPPING:
@@ -1,8 +1,10 @@
1
1
  import sys
2
2
  import time
3
+ from typing import Callable
3
4
 
4
5
  DELAY = 5
5
6
 
7
+
6
8
  if __name__ == "__main__":
7
9
  print("This script will allow you to reindex all indexes in elasticsearch.")
8
10
  print("For obvious reasons, be EXTREMELY CAREFUL running this code.")
@@ -11,7 +13,7 @@ if __name__ == "__main__":
11
13
  print(f"Continuing in {str(DELAY - i)}...", end="\r")
12
14
  time.sleep(1)
13
15
  print()
14
- answer = input("Are you sure you want to reindex all data in this cluster? [yes/NO]\n")
16
+ answer = input("Are you sure you want to reindex data for an index in this cluster? [yes/NO]\n")
15
17
 
16
18
  if not answer.startswith("y"):
17
19
  print("Confirmation not provided, stopping.")
@@ -25,10 +27,28 @@ if __name__ == "__main__":
25
27
 
26
28
  ds = loader.datastore(archive_access=False)
27
29
 
30
+ indexes: dict[str, tuple[list[str], Callable]] = {
31
+ "analytic": (ds.analytic.index_list_full, ds.analytic.reindex),
32
+ "hit": (ds.hit.index_list_full, ds.hit.reindex),
33
+ "view": (ds.view.index_list_full, ds.view.reindex),
34
+ "template": (ds.template.index_list_full, ds.template.reindex),
35
+ "overview": (ds.overview.index_list_full, ds.overview.reindex),
36
+ "action": (ds.action.index_list_full, ds.action.reindex),
37
+ "user": (ds.user.index_list_full, ds.user.reindex),
38
+ "dossier": (ds.dossier.index_list_full, ds.dossier.reindex),
39
+ }
40
+
41
+ print("Which index will you reindex?")
42
+ index_answer = input(", ".join(indexes.keys()) + "\n> ")
43
+
44
+ if index_answer not in indexes:
45
+ print("Invalid index provided, stopping.")
46
+ sys.exit(1)
47
+
28
48
  print("You will be reindexing the following indexes:")
29
- print("\n".join(ds.hit.index_list_full))
49
+ print("\n".join(indexes[index_answer][0]))
30
50
 
31
- answer = input(("\nAre you sure you want to reindex all indexes? [yes/NO]\n"))
51
+ answer = input(("\nAre you sure you want to reindex these indexes? [yes/NO]\n"))
32
52
  print()
33
53
 
34
54
  if not answer.startswith("y"):
@@ -41,6 +61,6 @@ if __name__ == "__main__":
41
61
 
42
62
  print()
43
63
 
44
- result = ds.hit.reindex()
64
+ result = indexes[index_answer][1]()
45
65
 
46
66
  print(f"Reindex complete. Success: {result}.")
howler/odm/base.py CHANGED
@@ -643,6 +643,27 @@ class Integer(_Field):
643
643
  raise HowlerValueError(f"[{'.'.join(context)}]: {str(e)}")
644
644
 
645
645
 
646
+ class Long(_Field):
647
+ """
648
+ A field storing a long value. Equivalent to Integer in python, but sets the ES datatype to long.
649
+
650
+ In Elasticsearch, Integer supports values from -2^31 to 2^31-1, while Long supports values from -2^63 to 2^63-1.
651
+ """
652
+
653
+ def check(self, value, context=[], **kwargs):
654
+ if self.optional and value is None:
655
+ return None
656
+
657
+ if value is None or value == "":
658
+ if self.default_set:
659
+ return self.default
660
+
661
+ try:
662
+ return int(value)
663
+ except ValueError as e:
664
+ raise HowlerValueError(f"[{'.'.join(context)}]: {str(e)}")
665
+
666
+
646
667
  class Float(_Field):
647
668
  """A field storing a floating point value."""
648
669
 
@@ -62,7 +62,7 @@ class Analytic(odm.Model):
62
62
  default=[],
63
63
  description="A list of useful notebooks for the analytic",
64
64
  )
65
- name: str = odm.Keyword(description="The name of the analytic.")
65
+ name: str = odm.CaseInsensitiveKeyword(description="The name of the analytic.")
66
66
  owner: Optional[str] = odm.Keyword(description="The username of the user who owns this analytic.", optional=True)
67
67
  contributors: list[str] = odm.List(
68
68
  odm.Keyword(),
@@ -71,7 +71,7 @@ class Analytic(odm.Model):
71
71
  )
72
72
  description: Optional[str] = odm.Text(description="A markdown description of the analytic", optional=True)
73
73
  detections: list[str] = odm.List(
74
- odm.Keyword(),
74
+ odm.CaseInsensitiveKeyword(),
75
75
  description="The detections which this analytic contains.",
76
76
  default=[],
77
77
  )
@@ -117,7 +117,7 @@ class Client(odm.Model):
117
117
  description="Collection of connected Internal Protocol routing prefixes",
118
118
  )
119
119
  )
120
- bytes: Optional[int] = odm.Optional(odm.Integer(description="Bytes sent from the client to the server."))
120
+ bytes: Optional[int] = odm.Optional(odm.Long(description="Bytes sent from the client to the server."))
121
121
  domain: Optional[str] = odm.Optional(odm.Keyword(description="The domain name of the client system."))
122
122
  geo: Geo = odm.Optional(
123
123
  odm.Compound(
@@ -161,10 +161,10 @@ class Log(odm.Model):
161
161
 
162
162
  @odm.model(index=True, store=True, description="Hit outline header.")
163
163
  class Header(odm.Model):
164
- threat: Optional[str] = odm.Optional(odm.Text(description="The IP of the threat."))
165
- target: Optional[str] = odm.Optional(odm.Text(description="The target of the hit."))
166
- indicators: list[str] = odm.List(odm.Text(description="Indicators of the hit."), default=[])
167
- summary: Optional[str] = odm.Optional(odm.Text(description="Summary of the hit."))
164
+ threat: Optional[str] = odm.Optional(odm.Keyword(description="The IP of the threat."))
165
+ target: Optional[str] = odm.Optional(odm.Keyword(description="The target of the hit."))
166
+ indicators: list[str] = odm.List(odm.Keyword(description="Indicators of the hit."), default=[])
167
+ summary: Optional[str] = odm.Optional(odm.Keyword(description="Summary of the hit."))
168
168
 
169
169
 
170
170
  @odm.model(index=True, store=True, description="Fields describing the location where this alert has been retained.")
@@ -176,15 +176,15 @@ class Incident(odm.Model):
176
176
 
177
177
  @odm.model(index=True, store=True, description="Labels for the hit")
178
178
  class Label(odm.Model):
179
- assignments = odm.List(odm.Text(description="List of assignments for the hit."), default=[])
180
- generic = odm.List(odm.Text(description="List of generic labels for the hit."), default=[])
181
- insight = odm.List(odm.Text(description="List of insight labels for the hit."), default=[])
182
- mitigation = odm.List(odm.Text(description="List of mitigation labels for the hit."), default=[])
183
- victim = odm.List(odm.Text(description="List of victim labels for the hit."), default=[])
184
- campaign = odm.List(odm.Text(description="List of campaign labels for the hit."), default=[])
185
- threat = odm.List(odm.Text(description="List of threat labels for the hit."), default=[])
186
- tuning = odm.List(odm.Text(description="List of tuning labels for the hit."), default=[])
187
- operation = odm.List(odm.Text(description="List of operation labels for the hit."), default=[])
179
+ assignments = odm.List(odm.Keyword(description="List of assignments for the hit."), default=[])
180
+ generic = odm.List(odm.Keyword(description="List of generic labels for the hit."), default=[])
181
+ insight = odm.List(odm.Keyword(description="List of insight labels for the hit."), default=[])
182
+ mitigation = odm.List(odm.Keyword(description="List of mitigation labels for the hit."), default=[])
183
+ victim = odm.List(odm.Keyword(description="List of victim labels for the hit."), default=[])
184
+ campaign = odm.List(odm.Keyword(description="List of campaign labels for the hit."), default=[])
185
+ threat = odm.List(odm.Keyword(description="List of threat labels for the hit."), default=[])
186
+ tuning = odm.List(odm.Keyword(description="List of tuning labels for the hit."), default=[])
187
+ operation = odm.List(odm.Keyword(description="List of operation labels for the hit."), default=[])
188
188
 
189
189
 
190
190
  @odm.model(index=True, store=True, description="Votes for the hit")
howler/odm/models/view.py CHANGED
@@ -14,7 +14,7 @@ class Settings(odm.Model):
14
14
  @odm.model(index=True, store=True, description="Model of views")
15
15
  class View(odm.Model):
16
16
  view_id: str = odm.UUID(description="A UUID for this view")
17
- title: str = odm.Keyword(description="The name of this view.")
17
+ title: str = odm.CaseInsensitiveKeyword(description="The name of this view.")
18
18
  query: str = odm.Keyword(description="The query to run in this view.")
19
19
  sort: str = odm.Keyword(description="The sorting to use with this view.", optional=True)
20
20
  span: str = odm.Keyword(
howler/odm/randomizer.py CHANGED
@@ -32,6 +32,7 @@ from howler.odm import (
32
32
  Json,
33
33
  Keyword,
34
34
  List,
35
+ Long,
35
36
  LowerKeyword,
36
37
  Mapping,
37
38
  Model,
@@ -490,6 +491,8 @@ def random_data_for_field(field: _Field, name: str, minimal: bool = False) -> _A
490
491
  return get_random_iso_date()
491
492
  elif isinstance(field, Integer):
492
493
  return random.randint(128, 4096)
494
+ elif isinstance(field, Long):
495
+ return random.randint(1, 223372036854775807)
493
496
  elif isinstance(field, Float):
494
497
  return random.randint(12800, 409600) / 100.0
495
498
  elif isinstance(field, MD5):
howler/utils/lucene.py CHANGED
@@ -20,7 +20,7 @@ def try_parse_date(date: str) -> Optional[datetime]:
20
20
  return None
21
21
 
22
22
 
23
- def try_parse_number(number: str | int | float) -> Optional[Union[int, float]]:
23
+ def try_parse_number(number: Union[str, int, float]) -> Optional[Union[int, float]]:
24
24
  "Try and parse a number string into an integer or float type, or infinity. Returns None if string is invalid."
25
25
  if isinstance(number, (int, float)):
26
26
  return number
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: howler-api
3
- Version: 2.13.0.dev345
3
+ Version: 3.0.0.dev349
4
4
  Summary: Howler - API server
5
5
  License: MIT
6
6
  Keywords: howler,alerting,gc,canada,cse-cst,cse,cst,cyber,cccs
@@ -55,8 +55,8 @@ howler/cronjobs/view_cleanup.py,sha256=ULWLR1uFcRemRgkEDrMqmBamHiE0dgDvu49VK0qDk
55
55
  howler/datastore/README.md,sha256=ekWl1YJSrHlZpU5PgBkPEzPWjdbTdav6Rd2P0ccIesw,4758
56
56
  howler/datastore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  howler/datastore/bulk.py,sha256=VfolZfiaBD4ZTK3j6IVVVq4GMjVXb5elrsGwwM_nONE,2829
58
- howler/datastore/collection.py,sha256=psNzGxHncvWFWPb_s6SGq3LBnF31FAwyePnKMZL1VME,90223
59
- howler/datastore/constants.py,sha256=XjIxE9za_kx6OpvulzpnYcZ9c0GqvIaAKhvonjWRgZo,2387
58
+ howler/datastore/collection.py,sha256=YNDZ_x3q3Upq1PRD_2akOxcBp52FK52VrtzTf4wGWEQ,90363
59
+ howler/datastore/constants.py,sha256=x7ODomtOQmDjmXoAxly4onPAnUkq4BLZ1TBg-UgpU1g,2415
60
60
  howler/datastore/exceptions.py,sha256=yZvQXRI4mR50ltGFHbdZAD4TIbhdKJku6LLTPQ0JZRk,955
61
61
  howler/datastore/howler_store.py,sha256=kW7FKM-tILcfTmrjSB1yZm-ZnumPS_tiQEZUDaQoDkg,2915
62
62
  howler/datastore/migrations/fix_process.py,sha256=J0FxqcXbQ161sgmQ5teyEcPuX7WYB9wqs0CO8m1jk0U,1218
@@ -64,7 +64,7 @@ howler/datastore/operations.py,sha256=5WdJBewXRIG71ZexQcYASv0IYoDi1m9ia8332u5mXS
64
64
  howler/datastore/schemas.py,sha256=kuxqYVWMgqnrdU-ypkDxoSzEtECUrRCKXjU_R5Kg7X4,3158
65
65
  howler/datastore/store.py,sha256=MzIvZy8deMgpnKR-TKTTcttH6kkYy4EBSYMCh0Q-J0E,7055
66
66
  howler/datastore/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
- howler/datastore/support/build.py,sha256=5cX2Jl9vTgCWa_hiM-7LwxVm3pwHN5k0eiyGzHo11vE,7861
67
+ howler/datastore/support/build.py,sha256=iBVfWophzoPlx6rvR5w3Axb6gjqLuDeDBpKj7lO-1l0,7877
68
68
  howler/datastore/support/schemas.py,sha256=kuxqYVWMgqnrdU-ypkDxoSzEtECUrRCKXjU_R5Kg7X4,3158
69
69
  howler/datastore/types.py,sha256=TIMa_Je7d6QAujMK5nEuOSyom72Gwm-nDL9uKtIQ9qE,550
70
70
  howler/error.py,sha256=GPGLTmReKUDgT-D2jT4x4GtGW-R0tqV2LZp_VTM96dw,2755
@@ -72,7 +72,7 @@ howler/external/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  howler/external/generate_mitre.py,sha256=B4ALOP9OdAuq45u0UahprtFkG-B0SuMw-PwuUdZFFfM,2638
73
73
  howler/external/generate_sigma_rules.py,sha256=QkdgEtOYqazRqvc0sfkP_sZmooDbmog6BUfgTJ2zhPY,831
74
74
  howler/external/generate_tlds.py,sha256=S_J-x3QUaRjpZKOcBrnL8w7-FfTNKLOIrvW3qJDcj4Y,1386
75
- howler/external/reindex_data.py,sha256=ljk1InXrTSksnOYHjGxBZlKXmgzTt0O22TGOkgGpJyk,1260
75
+ howler/external/reindex_data.py,sha256=PHNivziWRi5EXemz3Eu0xQBWUkegJ-EMqgS_apVI6vw,2115
76
76
  howler/external/wipe_databases.py,sha256=CO_mUdezp24h6xz6Di_K5-Mid61d9EVcBO4ap5qnVao,1610
77
77
  howler/gunicorn_config.py,sha256=0X7DPFcVDu3qAgMbNsdYGqCuvQGn5ZNx_eapOMyuXuI,750
78
78
  howler/healthz.py,sha256=nvb8MBBERYIkA_UxxLIyNEQazYOnPCcm0sH0Jm5nF0k,769
@@ -86,13 +86,13 @@ howler/helper/workflow.py,sha256=fsYhjeZo1foM0J8AW3nMjTEJOAnh9R6L0f4ZL12pE4E,480
86
86
  howler/helper/ws.py,sha256=ONxC7DFYGQKpp0AmrFqQLeIyxOMD4nHk5i6lFyWOtqo,15911
87
87
  howler/odm/README.md,sha256=Ihc_DyjVQlLaIOEbPoQNPkum9Ecn8kn37-PMFQsX77s,5645
88
88
  howler/odm/__init__.py,sha256=1n6vgBOrFcCHSBFysqgODERvqP7s5DIeJe8N8UeE5pM,44
89
- howler/odm/base.py,sha256=UxWDNokfNIuQK-SQz8gjIznhc8lLQe6eJTF_7aIbwqQ,51620
89
+ howler/odm/base.py,sha256=uAgEaccEfoLZpNPlRheDzZTuDWTz-UJrTWNrKHeSFmo,52254
90
90
  howler/odm/charter.txt,sha256=-Wgrv7nqugZmeQknJk0_m6klLJStjVbuqKbi_KaDinQ,15277
91
91
  howler/odm/helper.py,sha256=EELMg3pvE7Kb9VDeKSYJQHiq6uCO2YuS095CPRgWrEM,13927
92
92
  howler/odm/howler_enum.py,sha256=JzRK3_adlhvfkoGdMZD1jgOwlneZs8-x7OxGEj3zcpY,768
93
93
  howler/odm/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  howler/odm/models/action.py,sha256=V9tgMCg1ewu8mOngTcA6QAPwaR0NIT71VHglpRFYmS4,1235
95
- howler/odm/models/analytic.py,sha256=zHrDgBgNWe49e1PMi2PydoaNU1d9f8xJh2wUG2q0z4I,3874
95
+ howler/odm/models/analytic.py,sha256=4m3EJ0ejA3dzUqymUV_Q2F2AtmP_aKSUzjS0u8MdK8M,3904
96
96
  howler/odm/models/assemblyline.py,sha256=_wcTiX3A6bhA2SGlK9tDF0v-uwLpIabXE8j2Fw91dGY,1596
97
97
  howler/odm/models/aws.py,sha256=pJVadJqubdgT27riCfp7bEKVP4XsMZB0ZUnKAbmCMd0,895
98
98
  howler/odm/models/azure.py,sha256=o7MZMMo9jh1SB8xXCajl_YSKP2nnnWsjx_DPT6LnQKg,710
@@ -102,7 +102,7 @@ howler/odm/models/dossier.py,sha256=Ob2qROrG2-DYzmVo2XVe4NJ8HjWGCoRAu2gPo6p9XGU,
102
102
  howler/odm/models/ecs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  howler/odm/models/ecs/agent.py,sha256=idSooyFCLuQAB7_RyEWTYW4-x9w5a3wpy2ct_-EDRQs,713
104
104
  howler/odm/models/ecs/autonomous_system.py,sha256=aR7xkKlLHsAOGJqsw-xzll7GXoetcR7PC1Y0Eko3kA8,541
105
- howler/odm/models/ecs/client.py,sha256=7WUr8VcKxo9iIsbAUFL8BcM-sXUFGoppBG9x7jC2Z60,5433
105
+ howler/odm/models/ecs/client.py,sha256=6W-KFG1dLC_P0npw83PPoj5a4_EaV_KZKz6YF9_K03A,5430
106
106
  howler/odm/models/ecs/cloud.py,sha256=jX_B6zULuQ_ORBBSn-1pxz3G313YEG4sya-OO9AVVTo,5933
107
107
  howler/odm/models/ecs/code_signature.py,sha256=mlv0TwNQdHlh51aotrMTZUmVHA8kH5jMMQuZBsia7Lg,1296
108
108
  howler/odm/models/ecs/container.py,sha256=PVhZfJoTdyCxpgSGPu6Rm1-PWF2q75ebn4vjDAEK25s,1315
@@ -139,16 +139,16 @@ howler/odm/models/ecs/user_agent.py,sha256=LM4ZjbdEkkF02zZu6Pg7j8JLuAyfliTC6PVAE
139
139
  howler/odm/models/ecs/vulnerability.py,sha256=iX2TUmCZTJjwyMcOmxiHg-pfoEwX8Wx-h8cxo5QsJmo,1553
140
140
  howler/odm/models/gcp.py,sha256=FLwaQVcfFeE5AbIhEB_Ge2UL-HjPdldY04Nrm9Mq7kk,675
141
141
  howler/odm/models/hit.py,sha256=kgzk3RzgKGvHdtNG0iMRxCtLPD73-BFFU9A_IxJcOHI,13396
142
- howler/odm/models/howler_data.py,sha256=3bzKQ_vSP_rK20S_U4PkXzsmBL1uqSaIOHZmoPuRkS8,12473
142
+ howler/odm/models/howler_data.py,sha256=pG0UbzvDEOI2googZVUSkBSrERn_u9ONNOgXoI4Jj94,12512
143
143
  howler/odm/models/lead.py,sha256=lqapGWZ4u22Asib48o7wAzramnFY9EkRybmb4olsyrA,904
144
144
  howler/odm/models/localized_label.py,sha256=G7gfQ1cngiI4KprqldHWE1KHkAgK4AG_JsfHxVRdsRs,361
145
145
  howler/odm/models/overview.py,sha256=kvZcMYPDlkJEGa0L1jq9pG0RFjLOVudC64-2GTWVu2w,684
146
146
  howler/odm/models/pivot.py,sha256=ZewcGh91xbE64snZ5Ahz2So1onAqO8U9H4CFe6jBOXs,1405
147
147
  howler/odm/models/template.py,sha256=-Tqq_36qD_3nQ4jv13OPeH_EyyERKhc55wT03CU-Kbk,979
148
148
  howler/odm/models/user.py,sha256=3V7cLxxHJwWfTsEdZ7-QZT_-PQL7H_RJ3buQ8AraGzQ,3052
149
- howler/odm/models/view.py,sha256=kmaJOXhR4prki5o0gBirs1dqGcQK3b9ATysL_kNoku0,1308
149
+ howler/odm/models/view.py,sha256=DYFrYcx4NT-Z_0GUg_5qjRRLwrMMFK78NQ-20iuFx8o,1323
150
150
  howler/odm/random_data.py,sha256=HHXKED3NMWF8fknrOy2JtsDfzuTWcIkK1N-dUlOLZzo,28441
151
- howler/odm/randomizer.py,sha256=-AG-C-FZEsZQp1bQGWLNIpx6NN6r1DcWtk6nq2Ktfwg,23595
151
+ howler/odm/randomizer.py,sha256=tWEHRfm8-HgSxpBbPAA8ACASZp0hbAH2naUkhN8rvjo,23692
152
152
  howler/patched.py,sha256=Br4BGU5raaqjSMDLD7ogb5A8Yn0dzecouh6uWVV2jlQ,77
153
153
  howler/plugins/__init__.py,sha256=P5P-t4KgIInOzp4NmIturNIhUbb3jPO81n55Q_b_gM0,841
154
154
  howler/plugins/config.py,sha256=75sGAPQPU9_dGkJJ8_Q1H1qIYEhu9iv8c0_PDgAJDAs,4802
@@ -189,12 +189,12 @@ howler/utils/chunk.py,sha256=NoVDKzZkO8O92xXk0s0Pny2g7It9BX0PqWbknmnRSFg,895
189
189
  howler/utils/dict_utils.py,sha256=EA0mq87r0RZP7SmiPZQukx3xXukM6EH2nhtQ6W2GAX4,6408
190
190
  howler/utils/isotime.py,sha256=iCGae-3OPS6PxQx76IwOpV_IRYc0wF9ezp61h7MifsY,449
191
191
  howler/utils/list_utils.py,sha256=DrpmdV5GJRw0XjoalPhP_368NUzh3L1pJT49ob6LovI,226
192
- howler/utils/lucene.py,sha256=ldouSi9yoZwDBNAxGTalz81LgCHNtyg2b_mL3xYGr4E,2395
192
+ howler/utils/lucene.py,sha256=26THuL0rt1ZUlOEVJYZ8d506WOqGrpCwEhfszsdKvLc,2400
193
193
  howler/utils/path.py,sha256=DfOU4i4zSs4wchHoE8iE7aWVLkTxiC_JRGepF2hBYBk,690
194
194
  howler/utils/socket_utils.py,sha256=nz1SklC9xBHUSfHyTJjpq3mbozX1GDf01WzdGxfaUII,2212
195
195
  howler/utils/str_utils.py,sha256=HE8Hqh2HlOLaj16w0H9zKOyDJLp-f1LQ50y_WeGZaEk,8389
196
196
  howler/utils/uid.py,sha256=p9dsqyvZ-lpiAuzZWCPCeEM99kdk0Ly9czf04HNdSuw,1341
197
- howler_api-2.13.0.dev345.dist-info/METADATA,sha256=toUPICFNLrwoUAhcTa1QGb2ljrlEsjMEeFTygiAH-N0,2805
198
- howler_api-2.13.0.dev345.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
199
- howler_api-2.13.0.dev345.dist-info/entry_points.txt,sha256=Lu9SBGvwe0wczJHmc-RudC24lmQk7tv3ZBXon9RIihg,259
200
- howler_api-2.13.0.dev345.dist-info/RECORD,,
197
+ howler_api-3.0.0.dev349.dist-info/METADATA,sha256=f6tF0ZIK5i3qHvI1466LjrU_GqzgTggGm4dbRKl7Ipk,2804
198
+ howler_api-3.0.0.dev349.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
199
+ howler_api-3.0.0.dev349.dist-info/entry_points.txt,sha256=Lu9SBGvwe0wczJHmc-RudC24lmQk7tv3ZBXon9RIihg,259
200
+ howler_api-3.0.0.dev349.dist-info/RECORD,,