taranis-models 1.3.4.dev2__tar.gz → 1.3.4.dev3__tar.gz

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.
Files changed (36) hide show
  1. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/PKG-INFO +1 -1
  2. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/assess.py +24 -7
  3. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/taranis_models.egg-info/PKG-INFO +1 -1
  4. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/taranis_models.egg-info/SOURCES.txt +1 -0
  5. taranis_models-1.3.4.dev3/tests/test_assess.py +30 -0
  6. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/.dockerignore +0 -0
  7. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/.gitignore +0 -0
  8. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/.python-version +0 -0
  9. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/LICENSE.md +0 -0
  10. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/README.md +0 -0
  11. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/__init__.py +0 -0
  12. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/admin.py +0 -0
  13. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/asset.py +0 -0
  14. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/base.py +0 -0
  15. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/dashboard.py +0 -0
  16. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/product.py +0 -0
  17. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/py.typed +0 -0
  18. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/report.py +0 -0
  19. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/types.py +0 -0
  20. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/models/user.py +0 -0
  21. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/pyproject.toml +0 -0
  22. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/setup.cfg +0 -0
  23. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/taranis_models.egg-info/dependency_links.txt +0 -0
  24. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/taranis_models.egg-info/requires.txt +0 -0
  25. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/taranis_models.egg-info/top_level.txt +0 -0
  26. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/__init__.pyi +0 -0
  27. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/admin.pyi +0 -0
  28. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/assess.pyi +0 -0
  29. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/asset.pyi +0 -0
  30. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/base.pyi +0 -0
  31. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/dashboard.pyi +0 -0
  32. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/product.pyi +0 -0
  33. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/report.pyi +0 -0
  34. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/types.pyi +0 -0
  35. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/typings/models/user.pyi +0 -0
  36. {taranis_models-1.3.4.dev2 → taranis_models-1.3.4.dev3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taranis-models
3
- Version: 1.3.4.dev2
3
+ Version: 1.3.4.dev3
4
4
  Summary: Taranis AI Models
5
5
  Maintainer-email: AIT <benjamin.akhras@ait.ac.at>
6
6
  License-Expression: EUPL-1.2
@@ -1,7 +1,7 @@
1
1
  import contextlib
2
2
  import hashlib
3
3
  import re
4
- from datetime import datetime
4
+ from datetime import datetime, timezone
5
5
  from typing import Any, Literal, Self
6
6
  from urllib.parse import quote
7
7
 
@@ -13,6 +13,23 @@ from pydantic import ValidationInfo, field_validator, model_validator
13
13
  from models.base import TaranisBaseModel
14
14
 
15
15
 
16
+ def _utcnow() -> datetime:
17
+ return datetime.now(timezone.utc).replace(tzinfo=None)
18
+
19
+
20
+ def _normalize_datetime(value: str | datetime | None) -> datetime | None:
21
+ if value is None:
22
+ return None
23
+ if isinstance(value, str):
24
+ with contextlib.suppress(ValueError):
25
+ value = datetime.fromisoformat(value)
26
+ if isinstance(value, str):
27
+ return None
28
+ if value.tzinfo is None or value.utcoffset() is None:
29
+ return value
30
+ return value.astimezone(timezone.utc).replace(tzinfo=None)
31
+
32
+
16
33
  class NewsItem(TaranisBaseModel):
17
34
  _core_endpoint = "/assess/news-items"
18
35
 
@@ -83,12 +100,7 @@ class NewsItem(TaranisBaseModel):
83
100
  @field_validator("published", "collected", mode="before")
84
101
  @classmethod
85
102
  def sanitize_date(cls, date: str | None | datetime) -> datetime:
86
- if isinstance(date, datetime):
87
- return date
88
- if isinstance(date, str):
89
- with contextlib.suppress(ValueError):
90
- return datetime.fromisoformat(date)
91
- return datetime.now()
103
+ return _normalize_datetime(date) or _utcnow()
92
104
 
93
105
 
94
106
  class StoryTag(TaranisBaseModel):
@@ -123,6 +135,11 @@ class Story(TaranisBaseModel):
123
135
  tags: list[dict[str, Any]] | None = None
124
136
  attributes: list[dict[str, Any]] | None = None
125
137
 
138
+ @field_validator("created", "updated", mode="before")
139
+ @classmethod
140
+ def sanitize_story_dates(cls, date: str | None | datetime) -> datetime | None:
141
+ return _normalize_datetime(date)
142
+
126
143
 
127
144
  class AssessSource(TaranisBaseModel):
128
145
  id: str | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taranis-models
3
- Version: 1.3.4.dev2
3
+ Version: 1.3.4.dev3
4
4
  Summary: Taranis AI Models
5
5
  Maintainer-email: AIT <benjamin.akhras@ait.ac.at>
6
6
  License-Expression: EUPL-1.2
@@ -21,6 +21,7 @@ taranis_models.egg-info/SOURCES.txt
21
21
  taranis_models.egg-info/dependency_links.txt
22
22
  taranis_models.egg-info/requires.txt
23
23
  taranis_models.egg-info/top_level.txt
24
+ tests/test_assess.py
24
25
  typings/models/__init__.pyi
25
26
  typings/models/admin.pyi
26
27
  typings/models/assess.pyi
@@ -0,0 +1,30 @@
1
+ from datetime import datetime
2
+
3
+ from models.assess import NewsItem, Story
4
+
5
+
6
+ def test_news_item_normalizes_aware_datetimes_to_utc_naive():
7
+ payload = NewsItem.model_validate(
8
+ {
9
+ "osint_source_id": "manual",
10
+ "title": "Test item",
11
+ "published": "2024-01-01T00:30:00+02:00",
12
+ "collected": "2024-01-01T01:30:00+02:00",
13
+ }
14
+ )
15
+
16
+ assert payload.published == datetime(2023, 12, 31, 22, 30)
17
+ assert payload.collected == datetime(2023, 12, 31, 23, 30)
18
+
19
+
20
+ def test_story_normalizes_aware_datetimes_to_utc_naive():
21
+ payload = Story.model_validate(
22
+ {
23
+ "id": "story-1",
24
+ "created": "2024-01-01T00:30:00+02:00",
25
+ "updated": "2024-01-01T01:30:00+02:00",
26
+ }
27
+ )
28
+
29
+ assert payload.created == datetime(2023, 12, 31, 22, 30)
30
+ assert payload.updated == datetime(2023, 12, 31, 23, 30)