PyDIET 0.9.3__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.
Files changed (177) hide show
  1. pydiet/__init__.py +12 -0
  2. pydiet/api_client/__init__.py +6 -0
  3. pydiet/api_client/client.py +57 -0
  4. pydiet/cmd/__init__.py +9 -0
  5. pydiet/cmd/start.py +107 -0
  6. pydiet/data/data_config.toml +242 -0
  7. pydiet/data/description.txt +1 -0
  8. pydiet/data/instruments/description.txt +1 -0
  9. pydiet/data/instruments/megacam/default +0 -0
  10. pydiet/data/instruments/megacam/description.txt +1 -0
  11. pydiet/data/instruments/megacam/detector/description.txt +1 -0
  12. pydiet/data/instruments/megacam/detector/qe/MegaCam_QE.average.fits +0 -0
  13. pydiet/data/instruments/megacam/detector/qe/description.txt +2 -0
  14. pydiet/data/instruments/megacam/filters/CaHK.MP9303.fits +0 -0
  15. pydiet/data/instruments/megacam/filters/Ha.MP9603.fits +0 -0
  16. pydiet/data/instruments/megacam/filters/HaOFF.MP9604.fits +0 -0
  17. pydiet/data/instruments/megacam/filters/M4112.MP9403.fits +0 -0
  18. pydiet/data/instruments/megacam/filters/M4376.MP9404.fits +0 -0
  19. pydiet/data/instruments/megacam/filters/OIII.MP9501.fits +0 -0
  20. pydiet/data/instruments/megacam/filters/OIIIOFF.MP9502.fits +0 -0
  21. pydiet/data/instruments/megacam/filters/description.txt +1 -0
  22. pydiet/data/instruments/megacam/filters/g.MP9402.fits +0 -0
  23. pydiet/data/instruments/megacam/filters/gri.MP9605.fits +0 -0
  24. pydiet/data/instruments/megacam/filters/i.MP9703.fits +0 -0
  25. pydiet/data/instruments/megacam/filters/r.MP9602.fits +0 -0
  26. pydiet/data/instruments/megacam/filters/u.MP9302.fits +0 -0
  27. pydiet/data/instruments/megacam/filters/z.MP9901.fits +0 -0
  28. pydiet/data/instruments/megacam/optics/description.txt +2 -0
  29. pydiet/data/instruments/megacam/optics/transmission/MegaPrime_transmission.fits +0 -0
  30. pydiet/data/instruments/megacam/optics/transmission/description.txt +2 -0
  31. pydiet/data/instruments/wircam/description.txt +1 -0
  32. pydiet/data/instruments/wircam/detector/description.txt +1 -0
  33. pydiet/data/instruments/wircam/detector/qe/WIRCam_QE.average.fits +0 -0
  34. pydiet/data/instruments/wircam/detector/qe/description.txt +2 -0
  35. pydiet/data/instruments/wircam/filters/BrG.WC8305.fits +0 -0
  36. pydiet/data/instruments/wircam/filters/CH4Off.WC8204.fits +0 -0
  37. pydiet/data/instruments/wircam/filters/CH4On.WC8203.fits +0 -0
  38. pydiet/data/instruments/wircam/filters/CO.WC8306.fits +0 -0
  39. pydiet/data/instruments/wircam/filters/H.WC8201.fits +0 -0
  40. pydiet/data/instruments/wircam/filters/H.WC8202.fits +0 -0
  41. pydiet/data/instruments/wircam/filters/H2.WC8304.fits +0 -0
  42. pydiet/data/instruments/wircam/filters/J.WC8101.fits +0 -0
  43. pydiet/data/instruments/wircam/filters/J.WC8103.fits +0 -0
  44. pydiet/data/instruments/wircam/filters/Kcont.WC8303.fits +0 -0
  45. pydiet/data/instruments/wircam/filters/Ks.WC8301.fits +0 -0
  46. pydiet/data/instruments/wircam/filters/Ks.WC8302.fits +0 -0
  47. pydiet/data/instruments/wircam/filters/LowOH1.WC8104.fits +0 -0
  48. pydiet/data/instruments/wircam/filters/LowOH2.WC8102.fits +0 -0
  49. pydiet/data/instruments/wircam/filters/W.WC8105.fits +0 -0
  50. pydiet/data/instruments/wircam/filters/Y.WC8002.fits +0 -0
  51. pydiet/data/instruments/wircam/filters/description.txt +1 -0
  52. pydiet/data/instruments/wircam/optics/description.txt +2 -0
  53. pydiet/data/instruments/wircam/optics/transmission/WIRCam_transmission.fits +0 -0
  54. pydiet/data/instruments/wircam/optics/transmission/description.txt +2 -0
  55. pydiet/data/sites/description.txt +1 -0
  56. pydiet/data/sites/mko/default +0 -0
  57. pydiet/data/sites/mko/description.txt +2 -0
  58. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.0.fits +0 -0
  59. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.1.fits +0 -0
  60. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.2.fits +0 -0
  61. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.3.fits +0 -0
  62. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.4.fits +0 -0
  63. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.5.fits +0 -0
  64. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.6.fits +0 -0
  65. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.7.fits +0 -0
  66. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.8.fits +0 -0
  67. pydiet/data/sites/mko/emission/MKO_emission.bright.AM1.9.fits +0 -0
  68. pydiet/data/sites/mko/emission/MKO_emission.bright.AM2.0.fits +0 -0
  69. pydiet/data/sites/mko/emission/MKO_emission.bright.AM2.5.fits +0 -0
  70. pydiet/data/sites/mko/emission/MKO_emission.bright.AM3.0.fits +0 -0
  71. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.0.fits +0 -0
  72. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.1.fits +0 -0
  73. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.2.fits +0 -0
  74. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.3.fits +0 -0
  75. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.4.fits +0 -0
  76. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.5.fits +0 -0
  77. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.6.fits +0 -0
  78. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.7.fits +0 -0
  79. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.8.fits +0 -0
  80. pydiet/data/sites/mko/emission/MKO_emission.dark.AM1.9.fits +0 -0
  81. pydiet/data/sites/mko/emission/MKO_emission.dark.AM2.0.fits +0 -0
  82. pydiet/data/sites/mko/emission/MKO_emission.dark.AM2.5.fits +0 -0
  83. pydiet/data/sites/mko/emission/MKO_emission.dark.AM3.0.fits +0 -0
  84. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.0.fits +0 -0
  85. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.1.fits +0 -0
  86. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.2.fits +0 -0
  87. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.3.fits +0 -0
  88. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.4.fits +0 -0
  89. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.5.fits +0 -0
  90. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.6.fits +0 -0
  91. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.7.fits +0 -0
  92. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.8.fits +0 -0
  93. pydiet/data/sites/mko/emission/MKO_emission.grey.AM1.9.fits +0 -0
  94. pydiet/data/sites/mko/emission/MKO_emission.grey.AM2.0.fits +0 -0
  95. pydiet/data/sites/mko/emission/MKO_emission.grey.AM2.5.fits +0 -0
  96. pydiet/data/sites/mko/emission/MKO_emission.grey.AM3.0.fits +0 -0
  97. pydiet/data/sites/mko/emission/description.txt +5 -0
  98. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.0.fits +0 -0
  99. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.1.fits +0 -0
  100. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.2.fits +0 -0
  101. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.3.fits +0 -0
  102. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.4.fits +0 -0
  103. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.5.fits +0 -0
  104. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.6.fits +0 -0
  105. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.7.fits +0 -0
  106. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.8.fits +0 -0
  107. pydiet/data/sites/mko/transmission/MKO_transmission.AM1.9.fits +0 -0
  108. pydiet/data/sites/mko/transmission/MKO_transmission.AM2.0.fits +0 -0
  109. pydiet/data/sites/mko/transmission/MKO_transmission.AM2.5.fits +0 -0
  110. pydiet/data/sites/mko/transmission/MKO_transmission.AM3.0.fits +0 -0
  111. pydiet/data/sites/mko/transmission/MKO_transmission.AM3.5.fits +0 -0
  112. pydiet/data/sites/mko/transmission/MKO_transmission.AM4.0.fits +0 -0
  113. pydiet/data/sites/mko/transmission/MKO_transmission.AM4.5.fits +0 -0
  114. pydiet/data/sites/mko/transmission/MKO_transmission.AM5.0.fits +0 -0
  115. pydiet/data/sites/mko/transmission/description.txt +5 -0
  116. pydiet/data/telescopes/cfht/default +0 -0
  117. pydiet/data/telescopes/cfht/description.txt +1 -0
  118. pydiet/data/telescopes/cfht/emission/description.txt +2 -0
  119. pydiet/data/telescopes/cfht/transmission/CFHT_M1_transmission.fits +0 -0
  120. pydiet/data/telescopes/cfht/transmission/description.txt +1 -0
  121. pydiet/data/telescopes/description.txt +1 -0
  122. pydiet/package.py +55 -0
  123. pydiet/py.typed +0 -0
  124. pydiet/server/__init__.py +9 -0
  125. pydiet/server/app.py +369 -0
  126. pydiet/server/config/__init__.py +51 -0
  127. pydiet/server/config/config.py +330 -0
  128. pydiet/server/config/fields.py +49 -0
  129. pydiet/server/config/settings.py +166 -0
  130. pydiet/server/data.py +31 -0
  131. pydiet/server/datafiles.py +367 -0
  132. pydiet/server/image.py +342 -0
  133. pydiet/server/models/__init__.py +34 -0
  134. pydiet/server/models/dataconfig.py +195 -0
  135. pydiet/server/models/default.py +9 -0
  136. pydiet/server/models/exceptions.py +9 -0
  137. pydiet/server/models/instrument.py +314 -0
  138. pydiet/server/models/query.py +172 -0
  139. pydiet/server/models/response.py +97 -0
  140. pydiet/server/models/types.py +35 -0
  141. pydiet/server/photsys.py +71 -0
  142. pydiet/server/response.py +237 -0
  143. pydiet/server/types/__init__.py +8 -0
  144. pydiet/server/types/quantity.py +532 -0
  145. pydiet/server/types/string.py +318 -0
  146. pydiet/templates/common/base.html +80 -0
  147. pydiet/templates/common/plot_filter.html +17 -0
  148. pydiet/templates/common/privacy.html +132 -0
  149. pydiet/templates/common/settings.html +23 -0
  150. pydiet/templates/common/terms.html +101 -0
  151. pydiet/templates/megacam/etc_form.html +319 -0
  152. pydiet/templates/megacam/etc_results.html +190 -0
  153. pydiet/templates/wircam/etc_form.html +319 -0
  154. pydiet/templates/wircam/etc_results.html +190 -0
  155. pydiet/web_client/css/style.css +221 -0
  156. pydiet/web_client/dist/pydiet.js +31 -0
  157. pydiet/web_client/images/logo.svg +6 -0
  158. pydiet/web_client/images/megacam/background.jpg +0 -0
  159. pydiet/web_client/images/megacam/logo.png +0 -0
  160. pydiet/web_client/images/wircam/background.jpg +0 -0
  161. pydiet/web_client/images/wircam/logo.png +0 -0
  162. pydiet/web_client/js/dom.js +51 -0
  163. pydiet/web_client/js/etc.js +63 -0
  164. pydiet/web_client/js/fetch.js +49 -0
  165. pydiet/web_client/js/instrument.js +62 -0
  166. pydiet/web_client/js/main.js +15 -0
  167. pydiet/web_client/js/plot.js +88 -0
  168. pydiet/web_client/js/settings.js +57 -0
  169. pydiet/web_client/js/theme.js +43 -0
  170. pydiet/web_client/js/url.js +12 -0
  171. pydiet/web_client/jsdoc.json +20 -0
  172. pydiet/web_client/package.json +83 -0
  173. pydiet-0.9.3.dist-info/METADATA +118 -0
  174. pydiet-0.9.3.dist-info/RECORD +177 -0
  175. pydiet-0.9.3.dist-info/WHEEL +4 -0
  176. pydiet-0.9.3.dist-info/entry_points.txt +5 -0
  177. pydiet-0.9.3.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,318 @@
1
+ """
2
+ Provide Pydantic-compatible annotations and annotated types for enhanced string
3
+ validation and serialization.
4
+ """
5
+ # Copyright UParisSaclay/CEA/CFHT/CNRS
6
+ # Licensed under the MIT licence
7
+
8
+ from __future__ import annotations
9
+
10
+ from re import compile
11
+ from typing import TYPE_CHECKING, Annotated, Any, Pattern
12
+
13
+ if TYPE_CHECKING:
14
+ from pydantic import GetCoreSchemaHandler
15
+ from pydantic import Field
16
+ from pydantic_core import core_schema
17
+
18
+
19
+
20
+ class StrAnnotation:
21
+ """
22
+ Pydantic compatible annotation for validating and serializing strings
23
+ (the original Pydantic 2.x string fields only support Rust Regex).
24
+
25
+ Examples
26
+ --------
27
+ >>> from typing import Annotated
28
+ >>> from pydantic import BaseModel
29
+ >>> from .string import StrAnnotation
30
+
31
+ >>> class Person(BaseModel):
32
+ ... firstname: Annotated[str, StrAnnotation(pattern=r"[A-Z][a-z]*")]
33
+ ... lastname: Annotated[str, StrAnnotation(pattern=r"[A-Z][a-z]*")]
34
+
35
+ >>> # The following instantiation validates
36
+ >>> user = Person(firstname="Emmanuel", lastname="Bertin")
37
+
38
+ >>> # The following instantiation does not validate
39
+ >>> user = Person(firstname="emmanuel", lastname="Bertin")
40
+ Traceback (most recent call last):
41
+ ...
42
+ pydantic_core._pydantic_core.ValidationError: 1 validation error for Person
43
+ firstname
44
+ Value error, string does not match [A-Z][a-z]* pattern
45
+ [type=value_error, input_value='emmanuel', input_type=str]
46
+ For further information visit https://errors.pydantic.dev/2.8/v/value_error
47
+
48
+ Parameters
49
+ ----------
50
+ description: str, optional
51
+ Description string.
52
+ min_length: int, optional
53
+ Minimum string length.
54
+ max_length: int, optional
55
+ Maximum string length.
56
+ pattern: Pattern, optional
57
+ Regular expression for validation.
58
+ valid_list: list[str], optional
59
+ List of validating strings.
60
+ """
61
+ description: str = ""
62
+ min_length: int | None = None
63
+ max_length: int | None = None
64
+ pattern: Pattern | None = None
65
+ valid_list: list[str] | None = None
66
+ def __init__(
67
+ self,
68
+ *,
69
+ description: str = "",
70
+ min_length: int | None = None,
71
+ max_length: int | None = None,
72
+ pattern: Pattern | None = None,
73
+ valid_list: list[str] | None = None):
74
+
75
+ self.description = description
76
+ self.min_length = min_length
77
+ self.max_length = max_length
78
+ self.pattern = pattern
79
+ if pattern is not None:
80
+ self.compiled = compile(pattern)
81
+ self.valid_list = valid_list
82
+
83
+
84
+ def validate(
85
+ self,
86
+ s: str,
87
+ info: core_schema.ValidationInfo | None = None) -> str:
88
+
89
+ """
90
+ Validate `str`.
91
+
92
+ Parameters
93
+ ----------
94
+ s: str
95
+ String that should be validated.
96
+ info: ~pydantic.core_schema.ValidationInfo, optional
97
+ The validation info provided by the Pydantic schema.
98
+
99
+ Returns
100
+ -------
101
+ s: str
102
+ Validated string.
103
+
104
+ Raises
105
+ ------
106
+ ValueError: exception
107
+ An error occurred validating the specified string.
108
+ It is raised if any of the following occur:
109
+ - the provided string did not match the pattern.
110
+ - An unknown type was provided for the string.
111
+ """
112
+ # Check if it is a string
113
+ if not isinstance(s, str):
114
+ raise ValueError("not a string")
115
+
116
+ # Check if it has the right size
117
+ if self.min_length and len(s) < self.min_length:
118
+ raise ValueError(f"String should have at least {self.min_length} characters")
119
+ if self.max_length and len(s) > self.max_length:
120
+ raise ValueError(f"String should have at most {self.max_length} characters")
121
+
122
+ # Check if it matches the regular expression if provided
123
+ if self.pattern and not self.compiled.match(s):
124
+ raise ValueError(f"String should match {self.pattern} pattern")
125
+
126
+ # Check if it matches any member of the list if provided
127
+ if self.valid_list and not s in self.valid_list:
128
+ raise ValueError(f"String should match any of {self.valid_list}")
129
+
130
+ return s
131
+
132
+
133
+ def serialize(
134
+ self,
135
+ s: str,
136
+ info: core_schema.SerializationInfo | None = None,
137
+ *,
138
+ to_json: bool = False) -> dict | str:
139
+ """
140
+ Serialize string.
141
+
142
+ Parameters
143
+ ----------
144
+ s: str
145
+ String that should be serialized.
146
+ info: pydantic.core_schema.SerializationInfo, optional
147
+ Serialization info provided by the Pydantic schema.
148
+ to_json: bool, optional
149
+ Whether or not to serialize to a json convertible object.
150
+
151
+ Returns
152
+ -------
153
+ s: str
154
+ The serialized `str`.
155
+ """
156
+ return s
157
+
158
+
159
+ def __get_pydantic_core_schema__(
160
+ self,
161
+ source_type: Any,
162
+ handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
163
+ """
164
+ Get the Pydantic core schema.
165
+
166
+ Parameters
167
+ ----------
168
+ source_type:
169
+ The source type.
170
+ handler: ~pydantic.GetCoreSchemaHandler
171
+ The `GetCoreSchemaHandler` instance.
172
+
173
+ Returns
174
+ -------
175
+ The Pydantic core schema.
176
+ """
177
+ _from_typedict_schema = {
178
+ "value": core_schema.typed_dict_field(
179
+ core_schema.str_schema()
180
+ ),
181
+ "str": core_schema.typed_dict_field(core_schema.str_schema()),
182
+ }
183
+
184
+ validate_schema = core_schema.chain_schema(
185
+ [
186
+ core_schema.union_schema(
187
+ [
188
+ core_schema.is_instance_schema(str),
189
+ core_schema.str_schema(
190
+ min_length=self.min_length,
191
+ max_length=self.max_length,
192
+ pattern=self.pattern
193
+ )
194
+ ]
195
+ ),
196
+ core_schema.with_info_plain_validator_function(self.validate),
197
+ ]
198
+ )
199
+
200
+ validate_json_schema = core_schema.chain_schema(
201
+ [
202
+ core_schema.str_schema(
203
+ min_length=self.min_length,
204
+ max_length=self.max_length,
205
+ pattern=self.pattern
206
+ ),
207
+ core_schema.no_info_plain_validator_function(self.validate)
208
+ ]
209
+ )
210
+
211
+ serialize_schema = core_schema.plain_serializer_function_ser_schema(
212
+ self.serialize,
213
+ info_arg=True,
214
+ )
215
+
216
+ return core_schema.json_or_python_schema(
217
+ json_schema=validate_json_schema,
218
+ python_schema=validate_schema,
219
+ serialization=serialize_schema,
220
+ )
221
+
222
+
223
+
224
+ def AnnotatedStr(
225
+ default: str,
226
+ short: str | None = None,
227
+ description: str = "",
228
+ min_length: int | None = None,
229
+ max_length: int | None = None,
230
+ pattern: Pattern | None = None,
231
+ valid_list: list[str] | None = None) -> Any:
232
+ """
233
+ Pydantic pseudo-field for validating and serializing strings
234
+ (the original Pydantic 2.x string fields only support Rust Regex).
235
+
236
+ Examples
237
+ --------
238
+ >>> from pydantic_settings import BaseSettings
239
+ >>> from .string import AnnotatedStr
240
+
241
+ >>> class Person(BaseSettings):
242
+ ... firstname: AnnotatedStr(
243
+ ... short='f',
244
+ ... description="First name.",
245
+ ... default="Unknown",
246
+ ... min_length=1,
247
+ ... pattern=r"[A-Z][a-z]*"
248
+ ... )
249
+ ... lastname: AnnotatedStr(
250
+ ... short='l',
251
+ ... description="Last name.",
252
+ ... default="Unknown",
253
+ ... min_length=1,
254
+ ... pattern=r"[A-Z][a-z]*"
255
+ ... )
256
+
257
+ >>> # The following instantiation validates
258
+ >>> user = Person(firstname="Emmanuel", lastname="Bertin")
259
+
260
+ >>> # The following instantiation does not validate
261
+ user = Person(firstname="emmanuel", lastname="Bertin")
262
+ Traceback (most recent call last):
263
+ ...
264
+ pydantic_core._pydantic_core.ValidationError: 1 validation error for Person
265
+ firstname
266
+ Value error, string does not match [A-Z][a-z]* pattern
267
+ [type=value_error, input_value='emmanuel', input_type=str]
268
+ For further information visit https://errors.pydantic.dev/2.8/v/value_error
269
+
270
+ Parameters
271
+ ----------
272
+ default: str | ~astropy.units.Quantity
273
+ Default value
274
+ short: str, optional
275
+ shortcut for keyword
276
+ description: str, optional
277
+ Description string.
278
+ min_length: int, optional
279
+ Minimum string length.
280
+ max_length: int, optional
281
+ Maximum string length.
282
+ pattern: Pattern, optional
283
+ Regular expression for validation.
284
+ valid_list: list[str], optional
285
+ List of validating strings.
286
+ """
287
+
288
+ json_extra: dict = {}
289
+ if default is not None:
290
+ json_extra['default'] = default
291
+ if max_length is not None:
292
+ json_extra['maxLength'] = str(max_length)
293
+ if min_length is not None:
294
+ json_extra['minLength'] = str(min_length)
295
+ if pattern is not None:
296
+ json_extra['pattern'] = str(pattern)
297
+ if valid_list is not None:
298
+ json_extra['valid_list'] = valid_list
299
+ if short:
300
+ json_extra['short'] = short
301
+ return Annotated[
302
+ str,
303
+ StrAnnotation(
304
+ min_length=min_length,
305
+ max_length=max_length,
306
+ pattern=pattern,
307
+ valid_list=valid_list
308
+ ),
309
+ Field(
310
+ default_factory=lambda: default,
311
+ description=description,
312
+ validate_default=True,
313
+ json_schema_extra=json_extra
314
+ )
315
+ ]
316
+
317
+
318
+
@@ -0,0 +1,80 @@
1
+ {#
2
+ # Base Jinja2 template for PyDIET client.
3
+ #
4
+ # Copyright CFHT/CNRS/OSUPS/CEA/UParisSaclay
5
+ # Licensed under the MIT licence
6
+ #}<!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="utf-8" />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <meta id="root_path" content="{{ root_path }}">
12
+ <link rel="icon" type="image/svg+xml" href="{{ root_path }}/client/images/logo.svg">
13
+ <title>{{ package.summary }}</title>
14
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"></script>
15
+ <script nomodule src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"></script>
16
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css" />
17
+ <link rel="stylesheet" href="{{ root_path }}/client/css/style.css" />
18
+ {% block headcontent %}{% endblock headcontent %}
19
+ </head>
20
+ <body>
21
+ <ion-app>
22
+ <ion-header>
23
+ <ion-toolbar>
24
+ <ion-menu-button slot="start"><ion-icon name="options"></ion-icon></ion-menu-button>
25
+ <ion-title size="large">
26
+ <ion-item lines="none">
27
+ <h3 style="width:100%; display:flex; justify-content:space-between; align-items: baseline;">
28
+ <span>DIET</span>
29
+ <span style="font-size: 0.75rem; color: var(--ion-color-medium);">v{{ package.version }}</span>
30
+ </h3>
31
+ </ion-item>
32
+ </ion-title>
33
+ <div id=user-slot slot="end"></div>
34
+ </ion-toolbar>
35
+ </ion-header>
36
+ <ion-menu side="start" content-id="main-content" style="--min-width:20rem;">
37
+ {% include "common/settings.html" %}
38
+ <ion-footer-bar>
39
+ <ion-item-divider>
40
+ </ion-item-divider>
41
+ <ion-item href="{{ root_path ~ doc_url }}" rel="external" target="_blank">
42
+ <ion-icon name="book" slot="start"></ion-icon>
43
+ <ion-label>Documentation</ion-label>
44
+ </ion-item>
45
+ <ion-item href="{{ root_path }}/docs" rel="external" target="_blank">
46
+ <ion-icon name="code-slash" slot="start"></ion-icon>
47
+ <ion-label>Web API</ion-label>
48
+ </ion-item>
49
+ </ion-footer-bar>
50
+ </ion-menu>
51
+ <ion-content id="main-content">
52
+ <div id="content-slot"></div>
53
+ <div id="modal-slot"></div>
54
+ </ion-content>
55
+ <ion-footer>
56
+ <ion-toolbar >
57
+ <ion-item lines="none" slot="start">
58
+ <ion-note id="terms" style="align-self:center; cursor:pointer">Terms of Service</ion-note>
59
+ </ion-item>
60
+ <ion-fab horizontal="center" vertical="center">
61
+ <ion-fab-button href="https://cfht.hawaii.edu" color="light" size="small">
62
+ <ion-icon src="{{ root_path }}/client/images/logo.svg"></ion-icon>
63
+ </ion-fab-button>
64
+ </ion-fab>
65
+ <ion-item lines="none" slot="end">
66
+ <ion-note id="privacy" style="align-self:center; cursor:pointer">Privacy Policy</ion-note>
67
+ </ion-item>
68
+ </ion-toolbar>
69
+ </ion-footer>
70
+ <ion-modal trigger="terms">
71
+ {% include "common/terms.html" %}
72
+ </ion-modal>
73
+ <ion-modal trigger="privacy">
74
+ {% include "common/privacy.html" %}
75
+ </ion-modal>
76
+ </ion-app>
77
+ <script src="{{ root_path }}/client/dist/pydiet.js"></script>
78
+ </body>
79
+ </html>
80
+
@@ -0,0 +1,17 @@
1
+ {#
2
+ # Jinja2 template for plotting PyDIET filter curves.
3
+ #
4
+ # Copyright 2024,2025 CFHT/CNRS/OSUPS/CEA/UParisSaclay
5
+ # Licensed under the MIT licence
6
+ #}
7
+ <ion-modal is-open=true backdrop-dismiss=true style="--height:auto;">
8
+ <ion-card>
9
+ <ion-card-header>
10
+ <ion-card-title>Instrument+telescope transmission curve</ion-card-title>
11
+ </ion-card-header>
12
+ <ion-card-content>
13
+ <canvas id="filter-canvas" />
14
+ </ion-card-content>
15
+ </ion-card>
16
+ </ion-modal>
17
+
@@ -0,0 +1,132 @@
1
+ <ion-content class="ion-padding">
2
+ <ion-text color="medium">
3
+ <section class="privacy-policy">
4
+ <h1>Privacy Policy</h1>
5
+ <p><em>Last updated: March 17, 2026</em></p>
6
+
7
+ <p>
8
+ This Privacy Policy describes how <strong>PyDIET</strong>
9
+ (“the Service”), operated by <a href="https://www.cfht.hawaii.edu"><strong>CFHT</strong></a>, a
10
+ U.S.-based non-profit research organization, collects and uses information
11
+ when you access or use the Service.
12
+ </p>
13
+
14
+ <h2>1. Scope of the Service</h2>
15
+ <p>
16
+ The Service is an academic web-based exposure time calculator accessible
17
+ worldwide. It does not require user accounts or authentication.
18
+ </p>
19
+
20
+ <h2>2. Information We Collect</h2>
21
+
22
+ <h3>a. Information you provide</h3>
23
+ <p>
24
+ The Service does not require or collect personal information such as names,
25
+ email addresses, or account credentials.
26
+ </p>
27
+
28
+ <h3>b. Automatically collected information</h3>
29
+ <p>
30
+ When you access the Service, our servers may automatically record limited
31
+ technical information in standard server logs, including:
32
+ </p>
33
+ <ul>
34
+ <li>IP address</li>
35
+ <li>Date and time of requests</li>
36
+ <li>Requested URLs and query parameters</li>
37
+ <li>HTTP method (GET/POST)</li>
38
+ <li>User agent (browser or client information)</li>
39
+ </ul>
40
+ <p>
41
+ This information is collected solely for operational, security, and
42
+ debugging purposes.
43
+ </p>
44
+
45
+ <h3>c. Local storage</h3>
46
+ <p>
47
+ The Service may use your browser’s local storage to save application
48
+ settings, such as preferences. This data remains on your device and is not
49
+ transmitted to our servers.
50
+ </p>
51
+
52
+ <h2>3. Use of Information</h2>
53
+ <p>We use the limited data we collect to:</p>
54
+ <ul>
55
+ <li>Operate and maintain the Service</li>
56
+ <li>Monitor performance and ensure security</li>
57
+ <li>Diagnose technical issues and improve functionality</li>
58
+ </ul>
59
+ <p>
60
+ We do not use your data for profiling, advertising, or marketing purposes.
61
+ </p>
62
+
63
+ <h2>4. Legal Basis for Processing (EEA/UK users)</h2>
64
+ <p>
65
+ For users in the European Economic Area or the United Kingdom, processing
66
+ of technical log data is based on our legitimate interests in ensuring the
67
+ security, stability, and proper functioning of the Service.
68
+ </p>
69
+
70
+ <h2>5. Data Retention</h2>
71
+ <p>
72
+ Server logs are retained only for the minimum period required by applicable
73
+ laws and institutional policies, after which they are deleted or anonymized.
74
+ </p>
75
+
76
+ <h2>6. Data Sharing</h2>
77
+ <p>
78
+ We do not sell, rent, or share personal data with third parties.
79
+ </p>
80
+ <p>
81
+ Data may be disclosed only if required by law or as reasonably necessary to
82
+ protect the security and integrity of the Service.
83
+ </p>
84
+
85
+ <h2>7. International Users</h2>
86
+ <p>
87
+ The Service is operated from the United States. By using the Service, you
88
+ acknowledge that technical information described in this Privacy Policy may
89
+ be processed in the United States.
90
+ </p>
91
+
92
+ <h2>8. Your Rights</h2>
93
+ <p>
94
+ Depending on your jurisdiction, you may have rights regarding your personal
95
+ data, including rights to access, correct, delete, or object to certain
96
+ processing.
97
+ </p>
98
+ <p>
99
+ Because we do not maintain user accounts or directly identifiable user
100
+ profiles, we may not be able to link technical log data to a specific
101
+ individual except where required by law and reasonably feasible.
102
+ </p>
103
+
104
+ <h2>9. Children’s Privacy</h2>
105
+ <p>
106
+ The Service is intended for academic and general audiences and does not
107
+ knowingly collect personal data from children.
108
+ </p>
109
+
110
+ <h2>10. Security</h2>
111
+ <p>
112
+ We implement reasonable technical and organizational measures to protect the
113
+ Service and associated data, including standard web security practices.
114
+ </p>
115
+
116
+ <h2>11. Changes to This Policy</h2>
117
+ <p>
118
+ This Privacy Policy may be updated from time to time. Updates will be
119
+ posted on this page with a revised “Last updated” date.
120
+ </p>
121
+
122
+ <h2>12. Contact</h2>
123
+ <p>
124
+ For questions about this Privacy Policy, please contact:
125
+ </p>
126
+ <p>
127
+ <a href="mailto:info@cfht.hawaii.edu">info@cfht.hawaii.edu</a>
128
+ </p>
129
+ </section>
130
+ </ion-text>
131
+ </ion-content>
132
+
@@ -0,0 +1,23 @@
1
+ {#
2
+ # Jinja2 template for PyDIET Settings section.
3
+ #
4
+ # Copyright CFHT/CNRS/OSUPS/CEA/UParisSaclay
5
+ # Licensed under the MIT licence
6
+ #}
7
+ <ion-list>
8
+ <ion-list-header>Settings</ion-list-header>
9
+ <ion-item slot="start">
10
+ <ion-label position="fixed">Theme</ion-label>
11
+ <ion-segment id="theme-segment" slot="end" value="auto" scrollable=true mode="ios">
12
+ {# Theme radio buttons will be inserted here by JS code #}
13
+ </ion-segment>
14
+ </ion-item>
15
+ <ion-item-divider></ion-item-divider>
16
+ <ion-item slot="start">
17
+ <ion-label position="fixed">Instrument</ion-label>
18
+ <ion-segment id="instrument-segment" value="megacam" scrollable=true mode="ios">
19
+ {# Instrument radio buttons will be inserted here by JS code #}
20
+ </ion-segment>
21
+ </ion-item>
22
+ </ion-list>
23
+
@@ -0,0 +1,101 @@
1
+ <ion-content class="ion-padding">
2
+ <ion-text color="medium">
3
+ <section class="terms-of-service">
4
+ <h1>Terms of Service</h1>
5
+ <p><em>Last updated: March 17, 2026</em></p>
6
+
7
+ <p>
8
+ These Terms of Service (“Terms”) govern your use of
9
+ <strong>PyDIET</strong> (the “Service”), operated by
10
+ <a href="https://www.cfht.hawaii.edu"><strong>CFHT</strong></a>, a
11
+ U.S.-based non-profit research organization.
12
+ By accessing or using the Service, you agree to these Terms.
13
+ </p>
14
+
15
+ <h2>1. Description of the Service</h2>
16
+ <p>
17
+ The Service provides an exposure time calculator (ETC) intended for
18
+ academic, research, and educational purposes. The Service is provided
19
+ without user authentication and may be accessed via a web interface or API.
20
+ </p>
21
+
22
+ <h2>2. Open Source Software</h2>
23
+ <p>
24
+ The underlying code of the Service is made available under the MIT License.
25
+ Your use of the source code is governed by the terms of that license.
26
+ </p>
27
+
28
+ <h2>3. No Warranty</h2>
29
+ <p>
30
+ The Service is provided “as is” and “as available,” without warranty of any
31
+ kind, express or implied, including but not limited to warranties of
32
+ accuracy, reliability, fitness for a particular purpose, or non-infringement.
33
+ </p>
34
+ <p>
35
+ The results produced by the Service are estimates only and may not reflect
36
+ actual observational or instrumental performance.
37
+ </p>
38
+
39
+ <h2>4. Limitation of Liability</h2>
40
+ <p>
41
+ To the fullest extent permitted by applicable law, CFHT shall
42
+ not be liable for any direct, indirect, incidental, consequential, or
43
+ special damages arising out of or in connection with the use of, or inability
44
+ to use, the Service, including but not limited to errors in calculations,
45
+ scientific results, or observational planning.
46
+ </p>
47
+
48
+ <h2>5. Use of the Service</h2>
49
+ <p>
50
+ You agree to use the Service only for lawful purposes and in a manner
51
+ consistent with its intended academic and research use. You are solely
52
+ responsible for how you interpret and use the results.
53
+ </p>
54
+
55
+ <h2>6. Modifications to the Service</h2>
56
+ <p>
57
+ CFHT reserves the right to modify, update, or discontinue any
58
+ aspect of the Service at any time without notice.
59
+ </p>
60
+ <p>
61
+ This includes, but is not limited to, changes in instrument models,
62
+ calibration data, algorithms, or implementation details, which may result
63
+ in differences in the outputs produced by the Service over time.
64
+ </p>
65
+
66
+ <h2>7. Availability</h2>
67
+ <p>
68
+ The Service may be unavailable from time to time due to maintenance,
69
+ updates, or technical issues. No guarantee of uptime or availability is
70
+ provided.
71
+ </p>
72
+
73
+ <h2>8. Third-Party Use and API</h2>
74
+ <p>
75
+ The Service may be accessed programmatically via an API. Excessive or abusive
76
+ use may be restricted to ensure fair access and system stability.
77
+ </p>
78
+
79
+ <h2>9. Governing Law</h2>
80
+ <p>
81
+ These Terms shall be governed by and construed in accordance with the laws
82
+ of the United States, without regard to conflict of law principles.
83
+ </p>
84
+
85
+ <h2>10. Changes to These Terms</h2>
86
+ <p>
87
+ These Terms may be updated from time to time. Continued use of the Service
88
+ after changes are posted constitutes acceptance of the revised Terms.
89
+ </p>
90
+
91
+ <h2>11. Contact</h2>
92
+ <p>
93
+ For questions regarding these Terms, please contact:
94
+ </p>
95
+ <p>
96
+ <a href="mailto:info@cfht.hawaii.edu">info@cfht.hawaii.edu</a>
97
+ </p>
98
+ </section>
99
+ </ion-text>
100
+ </ion-content>
101
+