py-sensor-things 0.1.1__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.
@@ -0,0 +1,227 @@
1
+
2
+ # CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL-C
3
+
4
+ ## Avertissement
5
+
6
+ Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes préside à sa rédaction:
7
+
8
+ d'une part, le respect des principes de diffusion des logiciels libres: accès au code source, droits étendus conférés aux utilisateurs,
9
+ d'autre part, la désignation d'un droit applicable, le droit français, auquel elle est conforme, tant au regard du droit de la responsabilité civile que du droit de la propriété intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel.
10
+
11
+ Les auteurs de la licence CeCILL-C1 sont:
12
+
13
+ Commissariat à l'Energie Atomique - CEA, établissement public de recherche à caractère scientifique, technique et industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris.
14
+
15
+ Centre National de la Recherche Scientifique - CNRS, établissement public à caractère scientifique et technologique, dont le siège est situé 3 rue Michel-Ange, 75794 Paris cedex 16.
16
+
17
+ Institut National de Recherche en Informatique et en Automatique - INRIA, établissement public à caractère scientifique et technologique, dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex.
18
+
19
+ ## Préambule
20
+
21
+ Ce contrat est une licence de logiciel libre dont l'objectif est de conférer aux utilisateurs la liberté de modifier et de réutiliser le logiciel régi par cette licence.
22
+
23
+ L'exercice de cette liberté est assorti d'une obligation de remettre à la disposition de la communauté les modifications apportées au code source du logiciel afin de contribuer à son évolution.
24
+
25
+ L'accessibilité au code source et les droits de copie, de modification et de redistribution qui découlent de ce contrat ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limitée et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concédants successifs qu'une responsabilité restreinte.
26
+
27
+ A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc à des développeurs ou des professionnels avertis possédant des connaissances informatiques approfondies. Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve de le conserver en l'état, sans ajout ni suppression de clauses.
28
+
29
+ Ce contrat est susceptible de s'appliquer à tout logiciel dont le titulaire des droits patrimoniaux décide de soumettre l'exploitation aux dispositions qu'il contient.
30
+
31
+ ## Article 1 - DEFINITIONS
32
+
33
+ Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une lettre capitale, auront la signification suivante:
34
+
35
+ Contrat: désigne le présent contrat de licence, ses éventuelles versions postérieures et annexes.
36
+
37
+ Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas échéant sa documentation, dans leur état au moment de l'acceptation du Contrat par le Licencié.
38
+
39
+ Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et éventuellement de Code Objet et le cas échéant sa documentation, dans leur état au moment de leur première diffusion sous les termes du Contrat.
40
+
41
+ Logiciel Modifié: désigne le Logiciel modifié par au moins une Contribution Intégrée.
42
+
43
+ Code Source: désigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accès est nécessaire en vue de modifier le Logiciel.
44
+
45
+ Code Objet: désigne les fichiers binaires issus de la compilation du Code Source.
46
+
47
+ Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial.
48
+
49
+ Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le Contrat.
50
+
51
+ Contributeur: désigne le Licencié auteur d'au moins une Contribution Intégrée.
52
+
53
+ Concédant: désigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat.
54
+
55
+ Contribution Intégrée: désigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans le Code Source par tout Contributeur.
56
+
57
+ Module Lié: désigne un ensemble de fichiers sources y compris leur documentation qui, sans modification du Code Source, permet de réaliser des fonctionnalités ou services supplémentaires à ceux fournis par le Logiciel.
58
+
59
+ Logiciel Dérivé: désigne toute combinaison du Logiciel, modifié ou non, et d'un Module Lié.
60
+
61
+ Parties: désigne collectivement le Licencié et le Concédant.
62
+
63
+ Ces termes s'entendent au singulier comme au pluriel.
64
+
65
+ ## Article 2 - OBJET
66
+
67
+ Le Contrat a pour objet la concession par le Concédant au Licencié d'une licence non exclusive, cessible et mondiale du Logiciel telle que définie ci-après à l'article 5 pour toute la durée de protection des droits portant sur ce Logiciel.
68
+
69
+ ## Article 3 - ACCEPTATION
70
+
71
+ 3.1 L'acceptation par le Licencié des termes du Contrat est réputée acquise du fait du premier des faits suivants:
72
+
73
+ (i) le chargement du Logiciel par tout moyen notamment par téléchargement à partir d'un serveur distant ou par chargement à partir d'un support physique;
74
+ (ii) le premier exercice par le Licencié de l'un quelconque des droits concédés par le Contrat.
75
+
76
+ 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spécificités du Logiciel, à la restriction de garantie et à la limitation à un usage par des utilisateurs expérimentés a été mis à disposition du Licencié préalablement à son acceptation telle que définie à l'article 3.1 ci dessus et le Licencié reconnaît en avoir pris connaissance.
77
+
78
+ ## Article 4 - ENTREE EN VIGUEUR ET DUREE
79
+ 4.1 ENTREE EN VIGUEUR
80
+
81
+ Le Contrat entre en vigueur à la date de son acceptation par le Licencié telle que définie en 3.1.
82
+ 4.2 DUREE
83
+
84
+ Le Contrat produira ses effets pendant toute la durée légale de protection des droits patrimoniaux portant sur le Logiciel.
85
+
86
+ ## Article 5 - ETENDUE DES DROITS CONCEDES
87
+
88
+ Le Concédant concède au Licencié, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la durée du Contrat dans les conditions ci-après détaillées.
89
+
90
+ Par ailleurs, si le Concédant détient ou venait à détenir un ou plusieurs brevets d'invention protégeant tout ou partie des fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas opposer les éventuels droits conférés par ces brevets aux Licenciés successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concédant s'engage à faire reprendre les obligations du présent alinéa aux cessionnaires.
91
+ 5.1 DROIT D'UTILISATION
92
+
93
+ Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant aux domaines d'application, étant ci-après précisé que cela comporte:
94
+
95
+ la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme.
96
+
97
+ le chargement, l'affichage, l'exécution, ou le stockage du Logiciel sur tout support.
98
+
99
+ la possibilité d'en observer, d'en étudier, ou d'en tester le fonctionnement afin de déterminer les idées et principes qui sont à la base de n'importe quel élément de ce Logiciel; et ceci, lorsque le Licencié effectue toute opération de chargement, d'affichage, d'exécution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat.
100
+
101
+ 5.2 DROIT DE MODIFICATION
102
+
103
+ Le droit de modification comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en résultant. Il comprend en particulier le droit de créer un Logiciel Dérivé.
104
+
105
+ Le Licencié est autorisé à apporter toute modification au Logiciel sous réserve de mentionner, de façon explicite, son nom en tant qu'auteur de cette modification et la date de création de celle-ci.
106
+ 5.3 DROIT DE DISTRIBUTION
107
+
108
+ Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le marché à titre onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé.
109
+
110
+ Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou non, à des tiers dans les conditions ci-après détaillées.
111
+ 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION
112
+
113
+ Le Licencié est autorisé à distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée:
114
+
115
+ d'un exemplaire du Contrat,
116
+
117
+ d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9,
118
+
119
+ et que, dans le cas où seul le Code Objet du Logiciel est redistribué, le Licencié permette un accès effectif au Code Source complet du Logiciel pendant au moins toute la durée de sa distribution du Logiciel, étant entendu que le coût additionnel d'acquisition du Code Source ne devra pas excéder le simple coût de transfert des données.
120
+ 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE
121
+
122
+ Lorsque le Licencié apporte une Contribution Intégrée au Logiciel, les conditions de distribution du Logiciel Modifié en résultant sont alors soumises à l'intégralité des dispositions du Contrat.
123
+
124
+ Le Licencié est autorisé à distribuer le Logiciel Modifié sous forme de code source ou de code objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée:
125
+
126
+ d'un exemplaire du Contrat,
127
+
128
+ d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9,
129
+
130
+ et que, dans le cas où seul le code objet du Logiciel Modifié est redistribué, le Licencié permette un accès effectif à son code source complet pendant au moins toute la durée de sa distribution du Logiciel Modifié, étant entendu que le coût additionnel d'acquisition du code source ne devra pas excéder le simple coût de transfert des données.
131
+ 5.3.3 DISTRIBUTION DU LOGICIEL DERIVE
132
+
133
+ Lorsque le Licencié crée un Logiciel Dérivé, ce Logiciel Dérivé peut être distribué sous un contrat de licence autre que le présent Contrat à condition de respecter les obligations de mention des droits sur le Logiciel telles que définies à l'article 6.4. Dans le cas où la création du Logiciel Dérivé a nécessité une modification du Code Source le licencié s'engage à ce que:
134
+
135
+ le Logiciel Modifié correspondant à cette modification soit régi par le présent Contrat,
136
+ les Contributions Intégrées dont le Logiciel Modifié résulte soient clairement identifiées et documentées,
137
+ le Licencié permette un accès effectif au code source du Logiciel Modifié, pendant au moins toute la durée de la distribution du Logiciel Dérivé, de telle sorte que ces modifications puissent être reprises dans une version ultérieure du Logiciel, étant entendu que le coût additionnel d'acquisition du code source du Logiciel Modifié ne devra pas excéder le simple coût du transfert des données.
138
+
139
+ 5.3.4 COMPATIBILITE AVEC LA LICENCE CeCILL
140
+
141
+ Lorsqu'un Logiciel Modifié contient une Contribution Intégrée soumise au contrat de licence CeCILL, ou lorsqu'un Logiciel Dérivé contient un Module Lié soumis au contrat de licence CeCILL, les stipulations prévues au troisième item de l'article 6.4 sont facultatives.
142
+
143
+ ## Article 6 - PROPRIETE INTELLECTUELLE
144
+ 6.1 SUR LE LOGICIEL INITIAL
145
+
146
+ Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la faculté de modifier les conditions de diffusion de ce Logiciel Initial.
147
+
148
+ Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi par le Contrat et ce, pour la durée visée à l'article 4.2.
149
+ 6.2 SUR LES CONTRIBUTIONS INTEGREES
150
+
151
+ Le Licencié qui a développé une Contribution Intégrée est titulaire sur celle-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable.
152
+ 6.3 SUR LES MODULES LIES
153
+
154
+ Le Licencié qui a développé un Module Lié est titulaire sur celui-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable et reste libre du choix du contrat régissant sa diffusion dans les conditions définies à l'article 5.3.3.
155
+ 6.4 MENTIONS DES DROITS
156
+
157
+ Le Licencié s'engage expressément:
158
+
159
+ à ne pas supprimer ou modifier de quelque manière que ce soit les mentions de propriété intellectuelle apposées sur le Logiciel;
160
+
161
+ à reproduire à l'identique lesdites mentions de propriété intellectuelle sur les copies du Logiciel modifié ou non;
162
+ à faire en sorte que l'utilisation du Logiciel, ses mentions de propriété intellectuelle et le fait qu'il est régi par le Contrat soient indiqués dans un texte facilement accessible notamment depuis l'interface de tout Logiciel Dérivé.
163
+
164
+ Le Licencié s'engage à ne pas porter atteinte, directement ou indirectement, aux droits de propriété intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et à prendre, le cas échéant, à l'égard de son personnel toutes les mesures nécessaires pour assurer le respect des dits droits de propriété intellectuelle du Titulaire et/ou des Contributeurs.
165
+
166
+ ## Article 7 - SERVICES ASSOCIES
167
+
168
+ 7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de prestations d'assistance technique ou de maintenance du Logiciel.
169
+
170
+ Cependant le Concédant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors déterminés dans un acte séparé. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilité du Concédant qui les propose.
171
+
172
+ 7.2 De même, tout Concédant est libre de proposer, sous sa seule responsabilité, à ses licenciés une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, dans les conditions qu'il souhaite. Cette garantie et les modalités financières de son application feront l'objet d'un acte séparé entre le Concédant et le Licencié.
173
+
174
+ ## Article 8 - RESPONSABILITE
175
+
176
+ 8.1 Sous réserve des dispositions de l'article 8.2, le Licencié a la faculté, sous réserve de prouver la faute du Concédant concerné, de solliciter la réparation du préjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve.
177
+
178
+ 8.2 La responsabilité du Concédant est limitée aux engagements pris en application du Contrat et ne saurait être engagée en raison notamment: (i) des dommages dus à l'inexécution, totale ou partielle, de ses obligations par le Licencié, (ii) des dommages directs ou indirects découlant de l'utilisation ou des performances du Logiciel subis par le Licencié et (iii) plus généralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressément que tout préjudice financier ou commercial (par exemple perte de données, perte de bénéfices, perte d'exploitation, perte de clientèle ou de commandes, manque à gagner, trouble commercial quelconque) ou toute action dirigée contre le Licencié par un tiers, constitue un dommage indirect et n'ouvre pas droit à réparation par le Concédant.
179
+
180
+ ## Article 9 - GARANTIE
181
+
182
+ 9.1 Le Licencié reconnaît que l'état actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vérifier toutes les utilisations ni de détecter l'existence d'éventuels défauts. L'attention du Licencié a été attirée sur ce point sur les risques associés au chargement, à l'utilisation, la modification et/ou au développement et à la reproduction du Logiciel qui sont réservés à des utilisateurs avertis.
183
+
184
+ Il relève de la responsabilité du Licencié de contrôler, par tous moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens.
185
+
186
+ 9.2 Le Concédant déclare de bonne foi être en droit de concéder l'ensemble des droits attachés au Logiciel (comprenant notamment les droits visés à l'article 5).
187
+
188
+ 9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le Concédant sans autre garantie, expresse ou tacite, que celle prévue à l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractère sécurisé, innovant ou pertinent.
189
+
190
+ En particulier, le Concédant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'équipement du Licencié et sa configuration logicielle ni qu'il remplira les besoins du Licencié.
191
+
192
+ 9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le Logiciel ne porte pas atteinte à un quelconque droit de propriété intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de propriété. Ainsi, le Concédant exclut toute garantie au profit du Licencié contre les actions en contrefaçon qui pourraient être diligentées au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Néanmoins, si de telles actions sont exercées contre le Licencié, le Concédant lui apportera son aide technique et juridique pour sa défense. Cette aide technique et juridique est déterminée au cas par cas entre le Concédant concerné et le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage toute responsabilité quant à l'utilisation de la dénomination du Logiciel par le Licencié. Aucune garantie n'est apportée quant à l'existence de droits antérieurs sur le nom du Logiciel et sur l'existence d'une marque.
193
+
194
+ ## Article 10 - RESILIATION
195
+
196
+ 10.1 En cas de manquement par le Licencié aux obligations mises à sa charge par le Contrat, le Concédant pourra résilier de plein droit le Contrat trente (30) jours après notification adressée au Licencié et restée sans effet.
197
+
198
+ 10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concédées antérieurement à la résiliation du Contrat resteront valides sous réserve qu'elles aient été effectuées en conformité avec le Contrat.
199
+
200
+ ## Article 11 - DISPOSITIONS DIVERSES
201
+ 11.1 CAUSE EXTERIEURE
202
+
203
+ Aucune des Parties ne sera responsable d'un retard ou d'une défaillance d'exécution du Contrat qui serait dû à un cas de force majeure, un cas fortuit ou une cause extérieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du réseau électrique ou de télécommunication, la paralysie du réseau liée à une attaque informatique, l'intervention des autorités gouvernementales, les catastrophes naturelles, les dégâts des eaux, les tremblements de terre, le feu, les explosions, les grèves et les conflits sociaux, l'état de guerre...
204
+
205
+ 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intéressée à s'en prévaloir ultérieurement.
206
+
207
+ 11.3 Le Contrat annule et remplace toute convention antérieure, écrite ou orale, entre les Parties sur le même objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet à l'égard des Parties à moins d'être faite par écrit et signée par leurs représentants dûment habilités.
208
+
209
+ 11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat s'avèrerait contraire à une loi ou à un texte applicable, existants ou futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les amendements nécessaires pour se conformer à cette loi ou à ce texte. Toutes les autres dispositions resteront en vigueur. De même, la nullité, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraîner la nullité de l'ensemble du Contrat.
210
+ 11.5 LANGUE
211
+
212
+ Le Contrat est rédigé en langue française et en langue anglaise, ces deux versions faisant également foi.
213
+ ## Article 12 - NOUVELLES VERSIONS DU CONTRAT
214
+
215
+ 12.1 Toute personne est autorisée à copier et distribuer des copies de ce Contrat.
216
+
217
+ 12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé et ne peut être modifié que par les auteurs de la licence, lesquels se réservent le droit de publier périodiquement des mises à jour ou de nouvelles versions du Contrat, qui posséderont chacune un numéro distinct. Ces versions ultérieures seront susceptibles de prendre en compte de nouvelles problématiques rencontrées par les logiciels libres.
218
+
219
+ 12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra faire l'objet d'une diffusion ultérieure que sous la même version du Contrat ou une version postérieure.
220
+ ## Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE
221
+
222
+ 13.1 Le Contrat est régi par la loi française. Les Parties conviennent de tenter de régler à l'amiable les différends ou litiges qui viendraient à se produire par suite ou à l'occasion du Contrat.
223
+
224
+ 13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter de leur survenance et sauf situation relevant d'une procédure d'urgence, les différends ou litiges seront portés par la Partie la plus diligente devant les Tribunaux compétents de Paris.
225
+
226
+ 1 CeCILL est pour Ce(a) C(nrs) I(nria) L(ogiciel) L(ibre)
227
+ Version 1.0 du 2006-09-05.
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-sensor-things
3
+ Version: 0.1.1
4
+ Summary: Python packages for Sensor Thing API with request `https`
5
+ Author-email: Tberg <theo.berguig@free.fr>
6
+ License-Expression: BSD-3-Clause AND CC-BY-NC-4.0
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Topic :: System :: Monitoring
9
+ Classifier: Topic :: Scientific/Engineering :: GIS
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Requires-Python: >=3.12
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ # Python POC implementing standard for STA OGC API for real python
18
+
19
+ [![License: CC BY-NC 4.0](https://img.shields.io/badge/License-CC_BY--NC_4.0-lightgrey.svg?style=for-the-badge)](https://creativecommons.org/licenses/by-nc/4.0/)
20
+ ![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)
21
+ [![Static Badge OGC WPS](https://img.shields.io/badge/OGC-STApi-lightgreen?style=for-the-badge)](https://www.ogc.org/standards/sensorthings/)
22
+
23
+ ## Constate
24
+
25
+ This programme is an interface like :
26
+
27
+ ~~~
28
+ ┌───────────────┐ ┌...........┐ ┌───────────────┐
29
+ │ Client Python │──────▶ HTTP ─────▶│ Serveur STA │
30
+ └───────────────┘ └...........┘ └───────────────┘
31
+ ▲ │
32
+ └────────────────────────────────────┘
33
+ Give back data
34
+ ~~~
35
+
36
+ ## Usage:
37
+
38
+ ~~~python
39
+ from py_sta.model_sta import ModelSTA
40
+
41
+ url_sta = "http://.../v1.1/"
42
+
43
+ service = ModelSTA(url_sta)
44
+ # return pure dict object
45
+ model = (
46
+ service.observations()
47
+ .top(5)
48
+ .count()
49
+ .expand("FeatureOfInterest($select=@iot.id,name,feature)")
50
+ .order_by("phenomenonTime asc")
51
+ .execute()
52
+ )
53
+
54
+ result = [elem for elem in model["value"] ]
55
+ df_data = pandas.DataFrame(result)[["@iot.id","phenomenonTime","result"]]
56
+ # out
57
+ @iot.id phenomenonTime result
58
+ 0 47091 2025-02-09T15:10:00Z 515.0
59
+ 1 47203 2025-02-09T15:10:00Z 1941.0
60
+ 2 47092 2025-02-09T15:20:00Z 516.0
61
+ 3 47204 2025-02-09T15:20:00Z 1950.0
62
+ 4 47093 2025-02-09T15:30:00Z 516.0
63
+ ~~~
64
+
65
+
66
+ ### Print info
67
+
68
+ ~~~py
69
+ >>> service.info()
70
+ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮
71
+ 🌐 URL: https://data.geoscience.fr/api/stapi/surfacewater/insitu/v1.1/
72
+ 📅 Date min: 2025-02-09 15:10:00
73
+
74
+ 📅 Date max: 2025-08-11 15:15:00
75
+ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯
76
+
77
+ Route:
78
+ ╭─────────────────────┬──────────────────────────────────────────────╮
79
+ │ Name │ endpoint │
80
+ ├─────────────────────┼──────────────────────────────────────────────┤
81
+ │ Datastreams │ surfacewater/insitu/v1.1/Datastreams │
82
+ │ FeaturesOfInterest │ surfacewater/insitu/v1.1/FeaturesOfInterest │
83
+ │ HistoricalLocations │ surfacewater/insitu/v1.1/HistoricalLocations │
84
+ │ Locations │ surfacewater/insitu/v1.1/Locations │
85
+ │ Observations │ surfacewater/insitu/v1.1/Observations │
86
+ │ ObservedProperties │ surfacewater/insitu/v1.1/ObservedProperties │
87
+ │ Sensors │ surfacewater/insitu/v1.1/Sensors │
88
+ │ Things │ surfacewater/insitu/v1.1/Things │
89
+ ╰─────────────────────┴──────────────────────────────────────────────╯
90
+ ~~~
91
+
92
+ ## Next step
93
+
94
+ - [ ] TODO
95
+
96
+ # Credit
97
+
98
+ > [!IMPORTANT]
99
+ > Auteur : **Théo BERGUIG**
100
+ >
101
+ > No commercial, using code, contribute of code for projet **AND add cite this project**.
102
+ >
103
+ > **Date** : <ins>05/06/2026</ins>
@@ -0,0 +1,87 @@
1
+ # Python POC implementing standard for STA OGC API for real python
2
+
3
+ [![License: CC BY-NC 4.0](https://img.shields.io/badge/License-CC_BY--NC_4.0-lightgrey.svg?style=for-the-badge)](https://creativecommons.org/licenses/by-nc/4.0/)
4
+ ![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)
5
+ [![Static Badge OGC WPS](https://img.shields.io/badge/OGC-STApi-lightgreen?style=for-the-badge)](https://www.ogc.org/standards/sensorthings/)
6
+
7
+ ## Constate
8
+
9
+ This programme is an interface like :
10
+
11
+ ~~~
12
+ ┌───────────────┐ ┌...........┐ ┌───────────────┐
13
+ │ Client Python │──────▶ HTTP ─────▶│ Serveur STA │
14
+ └───────────────┘ └...........┘ └───────────────┘
15
+ ▲ │
16
+ └────────────────────────────────────┘
17
+ Give back data
18
+ ~~~
19
+
20
+ ## Usage:
21
+
22
+ ~~~python
23
+ from py_sta.model_sta import ModelSTA
24
+
25
+ url_sta = "http://.../v1.1/"
26
+
27
+ service = ModelSTA(url_sta)
28
+ # return pure dict object
29
+ model = (
30
+ service.observations()
31
+ .top(5)
32
+ .count()
33
+ .expand("FeatureOfInterest($select=@iot.id,name,feature)")
34
+ .order_by("phenomenonTime asc")
35
+ .execute()
36
+ )
37
+
38
+ result = [elem for elem in model["value"] ]
39
+ df_data = pandas.DataFrame(result)[["@iot.id","phenomenonTime","result"]]
40
+ # out
41
+ @iot.id phenomenonTime result
42
+ 0 47091 2025-02-09T15:10:00Z 515.0
43
+ 1 47203 2025-02-09T15:10:00Z 1941.0
44
+ 2 47092 2025-02-09T15:20:00Z 516.0
45
+ 3 47204 2025-02-09T15:20:00Z 1950.0
46
+ 4 47093 2025-02-09T15:30:00Z 516.0
47
+ ~~~
48
+
49
+
50
+ ### Print info
51
+
52
+ ~~~py
53
+ >>> service.info()
54
+ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮
55
+ 🌐 URL: https://data.geoscience.fr/api/stapi/surfacewater/insitu/v1.1/
56
+ 📅 Date min: 2025-02-09 15:10:00
57
+
58
+ 📅 Date max: 2025-08-11 15:15:00
59
+ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯
60
+
61
+ Route:
62
+ ╭─────────────────────┬──────────────────────────────────────────────╮
63
+ │ Name │ endpoint │
64
+ ├─────────────────────┼──────────────────────────────────────────────┤
65
+ │ Datastreams │ surfacewater/insitu/v1.1/Datastreams │
66
+ │ FeaturesOfInterest │ surfacewater/insitu/v1.1/FeaturesOfInterest │
67
+ │ HistoricalLocations │ surfacewater/insitu/v1.1/HistoricalLocations │
68
+ │ Locations │ surfacewater/insitu/v1.1/Locations │
69
+ │ Observations │ surfacewater/insitu/v1.1/Observations │
70
+ │ ObservedProperties │ surfacewater/insitu/v1.1/ObservedProperties │
71
+ │ Sensors │ surfacewater/insitu/v1.1/Sensors │
72
+ │ Things │ surfacewater/insitu/v1.1/Things │
73
+ ╰─────────────────────┴──────────────────────────────────────────────╯
74
+ ~~~
75
+
76
+ ## Next step
77
+
78
+ - [ ] TODO
79
+
80
+ # Credit
81
+
82
+ > [!IMPORTANT]
83
+ > Auteur : **Théo BERGUIG**
84
+ >
85
+ > No commercial, using code, contribute of code for projet **AND add cite this project**.
86
+ >
87
+ > **Date** : <ins>05/06/2026</ins>
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "py-sensor-things"
7
+ version = "0.1.1"
8
+ authors = [
9
+ { name="Tberg", email="theo.berguig@free.fr" },
10
+ ]
11
+ description = "Python packages for Sensor Thing API with request `https` "
12
+ readme = "Readme.md"
13
+ requires-python = ">=3.12"
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Topic :: System :: Monitoring",
17
+ "Topic :: Scientific/Engineering :: GIS",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ ]
21
+ license = "BSD-3-Clause and CC-BY-NC-4.0"
22
+ license-files = ["LICENSE"]
23
+
24
+ [tool.setuptools.packages.find]
25
+ where = ["src"]
26
+
27
+ [tool.pytest.ini_options]
28
+ addopts = "--cov=monmodule --cov-report=term-missing"
29
+
30
+ [tool.coverage.report]
31
+ show_missing = true
32
+
33
+ [tool.coverage.run]
34
+ branch = true
35
+ command_line = "-m unittest discover -s tests/"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,103 @@
1
+ Metadata-Version: 2.4
2
+ Name: py-sensor-things
3
+ Version: 0.1.1
4
+ Summary: Python packages for Sensor Thing API with request `https`
5
+ Author-email: Tberg <theo.berguig@free.fr>
6
+ License-Expression: BSD-3-Clause AND CC-BY-NC-4.0
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Topic :: System :: Monitoring
9
+ Classifier: Topic :: Scientific/Engineering :: GIS
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Requires-Python: >=3.12
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Dynamic: license-file
16
+
17
+ # Python POC implementing standard for STA OGC API for real python
18
+
19
+ [![License: CC BY-NC 4.0](https://img.shields.io/badge/License-CC_BY--NC_4.0-lightgrey.svg?style=for-the-badge)](https://creativecommons.org/licenses/by-nc/4.0/)
20
+ ![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)
21
+ [![Static Badge OGC WPS](https://img.shields.io/badge/OGC-STApi-lightgreen?style=for-the-badge)](https://www.ogc.org/standards/sensorthings/)
22
+
23
+ ## Constate
24
+
25
+ This programme is an interface like :
26
+
27
+ ~~~
28
+ ┌───────────────┐ ┌...........┐ ┌───────────────┐
29
+ │ Client Python │──────▶ HTTP ─────▶│ Serveur STA │
30
+ └───────────────┘ └...........┘ └───────────────┘
31
+ ▲ │
32
+ └────────────────────────────────────┘
33
+ Give back data
34
+ ~~~
35
+
36
+ ## Usage:
37
+
38
+ ~~~python
39
+ from py_sta.model_sta import ModelSTA
40
+
41
+ url_sta = "http://.../v1.1/"
42
+
43
+ service = ModelSTA(url_sta)
44
+ # return pure dict object
45
+ model = (
46
+ service.observations()
47
+ .top(5)
48
+ .count()
49
+ .expand("FeatureOfInterest($select=@iot.id,name,feature)")
50
+ .order_by("phenomenonTime asc")
51
+ .execute()
52
+ )
53
+
54
+ result = [elem for elem in model["value"] ]
55
+ df_data = pandas.DataFrame(result)[["@iot.id","phenomenonTime","result"]]
56
+ # out
57
+ @iot.id phenomenonTime result
58
+ 0 47091 2025-02-09T15:10:00Z 515.0
59
+ 1 47203 2025-02-09T15:10:00Z 1941.0
60
+ 2 47092 2025-02-09T15:20:00Z 516.0
61
+ 3 47204 2025-02-09T15:20:00Z 1950.0
62
+ 4 47093 2025-02-09T15:30:00Z 516.0
63
+ ~~~
64
+
65
+
66
+ ### Print info
67
+
68
+ ~~~py
69
+ >>> service.info()
70
+ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮
71
+ 🌐 URL: https://data.geoscience.fr/api/stapi/surfacewater/insitu/v1.1/
72
+ 📅 Date min: 2025-02-09 15:10:00
73
+
74
+ 📅 Date max: 2025-08-11 15:15:00
75
+ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯
76
+
77
+ Route:
78
+ ╭─────────────────────┬──────────────────────────────────────────────╮
79
+ │ Name │ endpoint │
80
+ ├─────────────────────┼──────────────────────────────────────────────┤
81
+ │ Datastreams │ surfacewater/insitu/v1.1/Datastreams │
82
+ │ FeaturesOfInterest │ surfacewater/insitu/v1.1/FeaturesOfInterest │
83
+ │ HistoricalLocations │ surfacewater/insitu/v1.1/HistoricalLocations │
84
+ │ Locations │ surfacewater/insitu/v1.1/Locations │
85
+ │ Observations │ surfacewater/insitu/v1.1/Observations │
86
+ │ ObservedProperties │ surfacewater/insitu/v1.1/ObservedProperties │
87
+ │ Sensors │ surfacewater/insitu/v1.1/Sensors │
88
+ │ Things │ surfacewater/insitu/v1.1/Things │
89
+ ╰─────────────────────┴──────────────────────────────────────────────╯
90
+ ~~~
91
+
92
+ ## Next step
93
+
94
+ - [ ] TODO
95
+
96
+ # Credit
97
+
98
+ > [!IMPORTANT]
99
+ > Auteur : **Théo BERGUIG**
100
+ >
101
+ > No commercial, using code, contribute of code for projet **AND add cite this project**.
102
+ >
103
+ > **Date** : <ins>05/06/2026</ins>
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ Readme.md
3
+ pyproject.toml
4
+ src/py_sensor_things.egg-info/PKG-INFO
5
+ src/py_sensor_things.egg-info/SOURCES.txt
6
+ src/py_sensor_things.egg-info/dependency_links.txt
7
+ src/py_sensor_things.egg-info/top_level.txt
8
+ src/py_sta/__init__.py
9
+ src/py_sta/model_sta.py
10
+ src/py_sta/pp.py
11
+ test/test_model_sta.py
File without changes
@@ -0,0 +1,210 @@
1
+ import requests
2
+ import json
3
+ import pandas as pad
4
+ import datetime
5
+ from . import pp
6
+
7
+ class ModelSTA:
8
+ def __init__(self, url_sta):
9
+ self.url = url_sta
10
+ self.date_min = self._get_date_min()
11
+ self.date_max = self._get_date_max()
12
+ self._server_routes, self._server_settings = self._build_setting()
13
+ self._query_params = {}
14
+ self._entity_name = None
15
+ self.data_object = None
16
+ # self._key_word = {"$top":None,"$skip":None,"$count":,"$orderBy":None,"$select":None,"$filter":None,"$expand":None}
17
+ # self._operation = {"eq":"==","ne":"!=","gt":">","ge":">=","lt":"<","le":"<=","and":"and","or":"or","not":"not"}
18
+
19
+ def info(self):
20
+ pp.display_info(self.url,self.date_min,self.date_max)
21
+ pp.afficher_tableau_route(self._server_routes)
22
+
23
+ def things(self):
24
+ self._entity_name = "Things"
25
+ return self
26
+
27
+ def locations(self):
28
+ self._entity_name = "Locations"
29
+ return self
30
+
31
+ def sensors(self):
32
+ self._entity_name = "Sensors"
33
+ return self
34
+
35
+ def datastreams(self):
36
+ self._entity_name = "Datastreams"
37
+ return self
38
+
39
+ def observed_propertys(self):
40
+ self._entity_name = "ObservedPropertys"
41
+ return self
42
+
43
+ def observations(self):
44
+ self._entity_name = "Observations"
45
+ return self
46
+
47
+ def feature_of_interests(self):
48
+ self._entity_name = "FeatureOfInterests"
49
+ return self
50
+
51
+ def historical_locations(self):
52
+ self._entity_name = "HistoricalLocations"
53
+ return self
54
+
55
+ def _build_setting(self):
56
+ try:
57
+ # Effectuer la requête HTTP
58
+ req = requests.get(self.url)
59
+ req.raise_for_status() # Lève une exception si le statut HTTP est une erreur (4xx, 5xx)
60
+ # Convertir la réponse en dictionnaire Python
61
+ dict_obj = req.json()
62
+ # Vérifier la structure attendue
63
+ if isinstance(dict_obj, dict) and set(dict_obj.keys()) == {
64
+ "value",
65
+ "serverSettings",
66
+ }:
67
+ route = {}
68
+ # construit un dictionnaire par "name"
69
+ # Things ==> $base_url$/v1.1/Things
70
+ for k in dict_obj["value"]:
71
+ route[k["name"]] = k["url"]
72
+ return route, dict_obj["serverSettings"]
73
+ else:
74
+ raise ValueError(
75
+ "La réponse ne contient pas les clés attendues ('value' et 'serverSettings')."
76
+ )
77
+
78
+ except requests.exceptions.RequestException as e:
79
+ print(f"Erreur {req.codes} lors de la requête HTTP : {e}")
80
+ return None, None # ou lever une exception personnalisée
81
+ except json.JSONDecodeError as e:
82
+ print(f"Erreur de décodage JSON : {e}")
83
+ return None, None
84
+ except ValueError as e:
85
+ print(f"Erreur de validation des données : {e}")
86
+ return None, None
87
+
88
+ # enddef
89
+
90
+ def top(self, n) -> "ModelSTA":
91
+ self._query_params["$top"] = str(n)
92
+ return self
93
+
94
+ def count(self):
95
+ self._query_params["$count"] = str(True)
96
+ return self
97
+
98
+ def order_by(self, *fields):
99
+ self._query_params["$orderBy"] = ",".join(fields)
100
+ return self
101
+
102
+ def select(self, *fields):
103
+ self._query_params["$select"] = ",".join(fields)
104
+ return self
105
+
106
+ def filter(self, param):
107
+ self._query_params["$select"] = str(param)
108
+ return self
109
+
110
+ def expand(self, *fields):
111
+ self._query_params["$expand"] = ",".join(fields)
112
+ return self
113
+
114
+ def _construct_query(self) -> str:
115
+ """conatnate string element
116
+ self._query_params
117
+ like
118
+ >>> "?$top=12&$count=True&$skip=5&$select=@iot.id,name&$orderBy='phenomenonTime desc"
119
+
120
+ Returns
121
+ -------
122
+ str
123
+ query construction returned
124
+ """
125
+ tmp = ""
126
+ for param in self._query_params:
127
+ tmp += f"{param}={self._query_params[param]}&"
128
+ tmp = tmp[:-1]
129
+ return "?" + tmp
130
+
131
+ # end
132
+ def _build_query_url(self):
133
+ if not self._entity_name or self._entity_name == None:
134
+ raise ValueError("Aucune entité nommée spécifiée. ex : /Thing ")
135
+ if not self._query_params:
136
+ raise ValueError("Aucune requête definie")
137
+
138
+ # construct query url
139
+ query = self._construct_query()
140
+ # TODO : create validate query
141
+ # all url have a slash /
142
+ return self.url + self._entity_name + query
143
+
144
+ # end
145
+ def execute(self) -> dict:
146
+ """execute
147
+
148
+ Returns
149
+ -------
150
+ dict
151
+ Give data json form Request HTTP
152
+
153
+ """
154
+ try:
155
+ req = requests.get(self._build_query_url())
156
+ req.raise_for_status()
157
+ self.data_object = req.json()
158
+ return self.data_object
159
+ except Exception as e:
160
+ raise e
161
+
162
+ # end
163
+ def to_pandas(self):
164
+ return pad.DataFrame(self.data_object)
165
+
166
+ def get_one_things(slef, id):
167
+ try:
168
+ req = requests.get(slef._server_routes["Things"] + f"({id})")
169
+ req.raise_for_status()
170
+ return req.json()
171
+ except requests.exceptions.RequestException as e:
172
+ print(f"Erreur lors de la requête HTTP verifier la requête : {e}")
173
+ return None
174
+ except json.JSONDecodeError as e:
175
+ print(f"Erreur de décodage JSON : {e}")
176
+ return None
177
+ except Exception as e:
178
+ print(f"Erreur : {e}")
179
+
180
+ # enddef
181
+
182
+ def _get_date_min(self):
183
+ min_date = json.loads(
184
+ requests.get(
185
+ self.url + "Observations?$top=1&$orderby=phenomenonTime%20asc"
186
+ ).content
187
+ )["value"][0]["phenomenonTime"]
188
+ return datetime.datetime.strptime(min_date, "%Y-%m-%dT%H:%M:%SZ")
189
+
190
+ # end
191
+
192
+ def _get_date_max(self):
193
+ max_date = json.loads(
194
+ requests.get(
195
+ self.url + "Observations?$top=1&$orderby=phenomenonTime%20desc"
196
+ ).content
197
+ )["value"][0]["phenomenonTime"]
198
+ return datetime.datetime.strptime(max_date, "%Y-%m-%dT%H:%M:%SZ")
199
+ # end
200
+
201
+ # ---- geter ----
202
+ @property
203
+ def get_routes(self):
204
+ return self._server_routes
205
+ # enddef
206
+
207
+ @property
208
+ def get_server_settings(self):
209
+ return self._server_settings
210
+ # enddef
@@ -0,0 +1,29 @@
1
+ from rich.table import Table
2
+ from rich.console import Console
3
+ from rich import box
4
+
5
+ # Initialiser la console Rich (une seule fois)
6
+ console = Console()
7
+
8
+ def afficher_tableau_route(obj_json):
9
+ titre="Route"
10
+ colonne_titre="endpoint"
11
+ console.print(f"\n[bold cyan]{titre}:[/bold cyan]",justify="center")
12
+ table = Table(box=box.ROUNDED,show_header=True, header_style="bold light_green")
13
+ table.add_column("Name", style="dim")
14
+ table.add_column(colonne_titre)
15
+
16
+ for element in list(obj_json.keys()):
17
+ table.add_row(str(element), ""+"/".join(str(obj_json[element]).split("/")[5:]))
18
+ console.print(table)
19
+
20
+
21
+ def display_info(url,date_min,date_max):
22
+ console.print(
23
+ f"╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮"
24
+ f" 🌐 URL: [bold]{url}[/bold]\n"
25
+ f" 📅 Date min: [green]{str(date_min)}[/green]\n\n"
26
+ f" 📅 Date max: [rgb(240,180,70)]{str(date_max)}[/rgb(240,180,70)]\n"
27
+ f"╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯"
28
+
29
+ )
@@ -0,0 +1,139 @@
1
+ import pytest
2
+ import requests
3
+ import json
4
+ import datetime
5
+ from py_sta.model_sta import ModelSTA
6
+
7
+
8
+ # =========================================================
9
+ # Fix data
10
+ # =========================================================
11
+ @pytest.fixture
12
+ def url_valide():
13
+ return "https://data.geoscience.fr/api/stapi/surfacewater/insitu/v1.1/"
14
+
15
+
16
+ @pytest.fixture
17
+ def url_unvalide():
18
+ return "http:/data.geoscience.fr/api/stapi/surfacewater/insitu"
19
+
20
+
21
+ @pytest.fixture
22
+ def model_init(url_valide):
23
+ return ModelSTA(url_valide)
24
+
25
+
26
+ @pytest.fixture
27
+ def json_data_1():
28
+ with open("test/data_test_req_1.json") as f:
29
+ return json.load(f)
30
+
31
+
32
+ @pytest.fixture
33
+ def json_ont_thing():
34
+ with open("test/data_test_one_things.json") as f:
35
+ return json.load(f)
36
+
37
+
38
+ @pytest.fixture
39
+ def json_data_expend():
40
+ with open("test/data_test_query_expend.json") as f:
41
+ return json.load(f)
42
+
43
+
44
+ # =========================================================
45
+ # TEST
46
+ # =========================================================
47
+
48
+
49
+ def test_init(url_valide):
50
+ model = ModelSTA(url_valide)
51
+ assert isinstance(model, ModelSTA)
52
+
53
+
54
+ def test_entity_len(model_init):
55
+ assert len(model_init._server_routes) == 8
56
+
57
+
58
+ def test_entity_name(model_init):
59
+ for k in model_init._server_routes:
60
+ match k:
61
+ case "Things":
62
+ assert model_init.things()._entity_name == k
63
+ case "Locations":
64
+ assert model_init.locations()._entity_name == k
65
+ case "Sensors":
66
+ assert model_init.sensors()._entity_name == k
67
+ case "Datastreams":
68
+ assert model_init.datastreams()._entity_name == k
69
+ case "ObservedPropertys":
70
+ assert model_init.observed_propertys()._entity_name == k
71
+ case "Observations":
72
+ assert model_init.observations()._entity_name == k
73
+ case "FeatureOfInterests":
74
+ assert model_init.feature_of_interests()._entity_name == k
75
+ case "HistoricalLocations":
76
+ assert model_init.historical_locations()._entity_name == k
77
+
78
+
79
+ def test_query(url_valide, json_data_1):
80
+ model = ModelSTA(url_valide)
81
+ req = model.observations().top(3).order_by("phenomenonTime desc").execute()
82
+ assert req == json_data_1
83
+
84
+
85
+ def test_one_thing(url_valide, json_ont_thing):
86
+ model = ModelSTA(url_valide)
87
+ one_thing = model.get_one_things(1)
88
+ assert one_thing == json_ont_thing
89
+
90
+
91
+ def test_data_min(url_valide):
92
+ model = ModelSTA(url_valide)
93
+ min_data = model._get_date_min()
94
+ assert min_data == datetime.datetime(2025, 2, 9, 15, 10) and isinstance(
95
+ min_data, datetime.datetime
96
+ )
97
+
98
+
99
+ def test_data(url_valide):
100
+ model = ModelSTA(url_valide)
101
+ min_data = model._get_date_min()
102
+ max_date = model._get_date_max()
103
+ assert min_data < max_date
104
+
105
+
106
+ def test_property_route(model_init):
107
+ assert model_init.get_routes == model_init._server_routes
108
+
109
+
110
+ def test_property_setting(model_init):
111
+ assert model_init.get_server_settings == model_init._server_settings
112
+
113
+
114
+ def test_query_expand(model_init, json_data_expend):
115
+ model = (
116
+ model_init.observations()
117
+ .top(5)
118
+ .count()
119
+ .expand("FeatureOfInterest($select=@iot.id,name,feature)")
120
+ .order_by("phenomenonTime asc")
121
+ .execute()
122
+ )
123
+ assert model == json_data_expend
124
+
125
+
126
+ # =========== Unvalide ===========
127
+
128
+
129
+ def test_error_init(url_unvalide):
130
+ with pytest.raises(requests.exceptions.InvalidURL):
131
+ ModelSTA(url_unvalide)
132
+
133
+
134
+ def test_error_one_thing(url_valide):
135
+ model = ModelSTA(url_valide)
136
+ assert model.get_one_things(-11) == None
137
+
138
+ # def test_error_build_setting(url_unvalide):
139
+ # model = ModelSTA(url_unvalide)