sfeos-helpers 6.7.3__py3-none-any.whl → 6.7.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sfeos_helpers
3
- Version: 6.7.3
3
+ Version: 6.7.5
4
4
  Summary: Helper library for the Elasticsearch and Opensearch stac-fastapi backends.
5
5
  Project-URL: Homepage, https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
6
  License: MIT
@@ -9,14 +9,12 @@ Classifier: Intended Audience :: Developers
9
9
  Classifier: Intended Audience :: Information Technology
10
10
  Classifier: Intended Audience :: Science/Research
11
11
  Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Programming Language :: Python :: 3.9
13
- Classifier: Programming Language :: Python :: 3.10
14
12
  Classifier: Programming Language :: Python :: 3.11
15
13
  Classifier: Programming Language :: Python :: 3.12
16
14
  Classifier: Programming Language :: Python :: 3.13
17
15
  Classifier: Programming Language :: Python :: 3.14
18
- Requires-Python: >=3.9
19
- Requires-Dist: stac-fastapi-core==6.7.3
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: stac-fastapi-core==6.7.5
20
18
  Description-Content-Type: text/markdown
21
19
 
22
20
  # sfeos-helpers
@@ -1,12 +1,12 @@
1
- stac_fastapi/sfeos_helpers/mappings.py,sha256=IqYd0tQUG-FnWVg6Fp1MU9audntF_-pMGm-BUTGbZMM,8596
2
- stac_fastapi/sfeos_helpers/version.py,sha256=xoqSv7gsqOZ-kd6XSuIGAoUwK4exieNAmUhNJv2SkHs,45
1
+ stac_fastapi/sfeos_helpers/mappings.py,sha256=AikPY20F7cqbiHHkFEmWdMtxruhfNJbYK7hugKq7qTQ,8602
2
+ stac_fastapi/sfeos_helpers/version.py,sha256=WRUWk2u8pozjztw-4p6a3fAkitIN0nGhe4tLZ6P6xUk,45
3
3
  stac_fastapi/sfeos_helpers/aggregation/README.md,sha256=SDlvCOpKyaJrlJvx84T2RzCnGALe_PK51zNeo3RP9ac,2122
4
4
  stac_fastapi/sfeos_helpers/aggregation/__init__.py,sha256=Mym17lFh90by1GnoQgMyIKAqRNJnvCgVSXDYzjBiPQk,1210
5
5
  stac_fastapi/sfeos_helpers/aggregation/client.py,sha256=PPUk0kAZnms46FlLGrR5w8wa52vG-dT6BG37896R5CY,17939
6
6
  stac_fastapi/sfeos_helpers/aggregation/format.py,sha256=qUW1jjh2EEjy-V7riliFR77grpi-AgsTmP76z60K5Lo,2011
7
7
  stac_fastapi/sfeos_helpers/database/README.md,sha256=TVYFDD4PqDD57ZsWBv4i4LawaL_DAEIOjM6OQuqwLAU,4049
8
8
  stac_fastapi/sfeos_helpers/database/__init__.py,sha256=Kvnz8hpXq_sSz8K5OW3PoPsvh9864Vv1zWhI5hxgd4o,2891
9
- stac_fastapi/sfeos_helpers/database/datetime.py,sha256=XMyi9Q09cuP_hj97qbGbHFtelq7WQVPdehUfzqNZFV4,4040
9
+ stac_fastapi/sfeos_helpers/database/datetime.py,sha256=XHS5mg9NXUi2P0FtBpjTjy-g7nRzCtFgp3juq6Fr1_M,6831
10
10
  stac_fastapi/sfeos_helpers/database/document.py,sha256=LtjX15gvaOuZC_k2t_oQhys_c-zRTLN5rwX0hNJkHnM,1725
11
11
  stac_fastapi/sfeos_helpers/database/index.py,sha256=g7_sKfd5XUwq4IhdKRNiasejk045dKlullsdeDSZTq8,6585
12
12
  stac_fastapi/sfeos_helpers/database/mapping.py,sha256=4-MSd4xH5wg7yoC4aPjzYMDSEvP026bw4k2TfffMT5E,1387
@@ -29,6 +29,6 @@ stac_fastapi/sfeos_helpers/search_engine/selection/base.py,sha256=106c4FK50cgMmT
29
29
  stac_fastapi/sfeos_helpers/search_engine/selection/cache_manager.py,sha256=5yrgf9JA4mgRNMPDKih6xySF8mD724lEWnXhWud7m2c,4039
30
30
  stac_fastapi/sfeos_helpers/search_engine/selection/factory.py,sha256=vbgNVCUW2lviePqzpgsPLxp6IEqcX3GHiahqN2oVObA,1305
31
31
  stac_fastapi/sfeos_helpers/search_engine/selection/selectors.py,sha256=q83nfCfNfLUqtkHpORwNHNRU9Pa-heeaDIPO0RlHb-8,4779
32
- sfeos_helpers-6.7.3.dist-info/METADATA,sha256=sgqsQ6xB_y1fRbwUTEOuBOihnr594ORi19tMEraQM_o,3214
33
- sfeos_helpers-6.7.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
- sfeos_helpers-6.7.3.dist-info/RECORD,,
32
+ sfeos_helpers-6.7.5.dist-info/METADATA,sha256=Uc87_remruIvFaSeGvZLSNhU-4RENX1f2E1DKK00ys8,3114
33
+ sfeos_helpers-6.7.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
+ sfeos_helpers-6.7.5.dist-info/RECORD,,
@@ -8,8 +8,10 @@ import logging
8
8
  import re
9
9
  from datetime import date
10
10
  from datetime import datetime as datetime_type
11
+ from datetime import timezone
11
12
  from typing import Dict, Optional, Union
12
13
 
14
+ from stac_fastapi.core.utilities import get_bool_env
13
15
  from stac_fastapi.types.rfc3339 import DateTimeType
14
16
 
15
17
  logger = logging.getLogger(__name__)
@@ -37,38 +39,103 @@ def return_date(
37
39
  always containing 'gte' and 'lte' keys.
38
40
  """
39
41
  result: Dict[str, Optional[str]] = {"gte": None, "lte": None}
40
-
42
+ use_datetime_nanos = get_bool_env("USE_DATETIME_NANOS", default=True)
41
43
  if interval is None:
42
44
  return result
43
45
 
44
- if isinstance(interval, str):
45
- if "/" in interval:
46
- parts = interval.split("/")
47
- result["gte"] = (
48
- parts[0] if parts[0] != ".." else datetime_type.min.isoformat() + "Z"
49
- )
50
- result["lte"] = (
51
- parts[1]
52
- if len(parts) > 1 and parts[1] != ".."
53
- else datetime_type.max.isoformat() + "Z"
46
+ if use_datetime_nanos:
47
+ MIN_DATE_NANOS = datetime_type(1970, 1, 1, tzinfo=timezone.utc)
48
+ MAX_DATE_NANOS = datetime_type(
49
+ 2262, 4, 11, 23, 47, 16, 854775, tzinfo=timezone.utc
50
+ )
51
+
52
+ if isinstance(interval, str):
53
+ if "/" in interval:
54
+ parts = interval.split("/")
55
+ result["gte"] = (
56
+ parts[0] if parts[0] != ".." else MIN_DATE_NANOS.isoformat() + "Z"
57
+ )
58
+ result["lte"] = (
59
+ parts[1]
60
+ if len(parts) > 1 and parts[1] != ".."
61
+ else MAX_DATE_NANOS.isoformat() + "Z"
62
+ )
63
+ else:
64
+ converted_time = interval if interval != ".." else None
65
+ result["gte"] = result["lte"] = converted_time
66
+ return result
67
+
68
+ if isinstance(interval, datetime_type):
69
+ dt_utc = (
70
+ interval.astimezone(timezone.utc)
71
+ if interval.tzinfo
72
+ else interval.replace(tzinfo=timezone.utc)
54
73
  )
55
- else:
56
- converted_time = interval if interval != ".." else None
57
- result["gte"] = result["lte"] = converted_time
74
+ if dt_utc < MIN_DATE_NANOS:
75
+ dt_utc = MIN_DATE_NANOS
76
+ elif dt_utc > MAX_DATE_NANOS:
77
+ dt_utc = MAX_DATE_NANOS
78
+ datetime_iso = dt_utc.isoformat()
79
+ result["gte"] = result["lte"] = datetime_iso
80
+ elif isinstance(interval, tuple):
81
+ start, end = interval
82
+ # Ensure datetimes are converted to UTC and formatted with 'Z'
83
+ if start:
84
+ start_utc = (
85
+ start.astimezone(timezone.utc)
86
+ if start.tzinfo
87
+ else start.replace(tzinfo=timezone.utc)
88
+ )
89
+ if start_utc < MIN_DATE_NANOS:
90
+ start_utc = MIN_DATE_NANOS
91
+ elif start_utc > MAX_DATE_NANOS:
92
+ start_utc = MAX_DATE_NANOS
93
+ result["gte"] = start_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
94
+ if end:
95
+ end_utc = (
96
+ end.astimezone(timezone.utc)
97
+ if end.tzinfo
98
+ else end.replace(tzinfo=timezone.utc)
99
+ )
100
+ if end_utc < MIN_DATE_NANOS:
101
+ end_utc = MIN_DATE_NANOS
102
+ elif end_utc > MAX_DATE_NANOS:
103
+ end_utc = MAX_DATE_NANOS
104
+ result["lte"] = end_utc.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
105
+
58
106
  return result
59
107
 
60
- if isinstance(interval, datetime_type):
61
- datetime_iso = interval.isoformat()
62
- result["gte"] = result["lte"] = datetime_iso
63
- elif isinstance(interval, tuple):
64
- start, end = interval
65
- # Ensure datetimes are converted to UTC and formatted with 'Z'
66
- if start:
67
- result["gte"] = start.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
68
- if end:
69
- result["lte"] = end.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
70
-
71
- return result
108
+ else:
109
+ if isinstance(interval, str):
110
+ if "/" in interval:
111
+ parts = interval.split("/")
112
+ result["gte"] = (
113
+ parts[0]
114
+ if parts[0] != ".."
115
+ else datetime_type.min.isoformat() + "Z"
116
+ )
117
+ result["lte"] = (
118
+ parts[1]
119
+ if len(parts) > 1 and parts[1] != ".."
120
+ else datetime_type.max.isoformat() + "Z"
121
+ )
122
+ else:
123
+ converted_time = interval if interval != ".." else None
124
+ result["gte"] = result["lte"] = converted_time
125
+ return result
126
+
127
+ if isinstance(interval, datetime_type):
128
+ datetime_iso = interval.isoformat()
129
+ result["gte"] = result["lte"] = datetime_iso
130
+ elif isinstance(interval, tuple):
131
+ start, end = interval
132
+ # Ensure datetimes are converted to UTC and formatted with 'Z'
133
+ if start:
134
+ result["gte"] = start.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
135
+ if end:
136
+ result["lte"] = end.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
137
+
138
+ return result
72
139
 
73
140
 
74
141
  def extract_date(date_str: str) -> date:
@@ -142,7 +142,7 @@ ES_ITEMS_MAPPINGS = {
142
142
  "type": "object",
143
143
  "properties": {
144
144
  # Common https://github.com/radiantearth/stac-spec/blob/master/item-spec/common-metadata.md
145
- "datetime": {"type": "date"},
145
+ "datetime": {"type": "date_nanos"},
146
146
  "start_datetime": {"type": "date"},
147
147
  "end_datetime": {"type": "date"},
148
148
  "created": {"type": "date"},
@@ -1,2 +1,2 @@
1
1
  """library version."""
2
- __version__ = "6.7.3"
2
+ __version__ = "6.7.5"