hidroconta 1.0.0__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,82 @@
1
+ Metadata-Version: 2.1
2
+ Name: hidroconta
3
+ Version: 1.0.0
4
+ Summary: API to easily access Demeter REST API provided by Hidroconta S.A.U.
5
+ Home-page: UNKNOWN
6
+ Author: JavierL
7
+ Author-email: javier.lopez@hidroconta.com
8
+ License: UNKNOWN
9
+ Platform: UNKNOWN
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Integrations-PythonAPI
16
+ API Python para facilitar el acceso a los endpoints de la interfaz REST de Demeter
17
+
18
+ La API permite la gestión de grandes cantidades de datos mediante la librería Pandas, siempre y cuando se utilice la siguiente directiva en las llamadas a los métodos:
19
+ ```
20
+ # Pandas = True returns a pandas dataframe instead a json
21
+ ```
22
+
23
+ La forma de usar la API es la siguiente:
24
+
25
+ - Importar los modulos deseados:
26
+ ```
27
+ import demeterpy as demeter
28
+ import demeterapitypes as tp
29
+ import pandas as pd
30
+ import datetime
31
+ import endpoints
32
+ ```
33
+ - Seleccionar el servidor con el cual se quiere comunicar (se puede modificar en todo momento):
34
+ ```
35
+ # Set server
36
+ demeter.set_server(endpoints.Server.MAIN)
37
+ ```
38
+
39
+ - Realizar el login en dicho servidor
40
+ ```
41
+ # Login
42
+ demeter.login('USERNAME', 'PASSWORD')
43
+ ```
44
+
45
+ Una vez seguidos los anteriores pasos, se puede realizar cualquier consulta sobre el sistema.
46
+ Algunas de ellas son:
47
+
48
+ - Búsqueda
49
+ ```
50
+ # Search
51
+ df = demeter.search(text='SAT', element_types=[tp.Element.COUNTER, tp.Element.ANALOG_INPUT, tp.Element.RTU], status=tp.Status.ENABLED, pandas=True)
52
+ print(df)
53
+ ```
54
+
55
+ - Obtención de historicos
56
+ ```
57
+ # Get historics
58
+ df = demeter.get_historics(start_date=datetime.datetime.now(), end_date=datetime.datetime.now(), element_ids=[1000], subtype=tp.AnalogInputHist.subtype, subcode=[tp.AnalogInputHist.subcode], pandas=True)
59
+ print(df)
60
+ ```
61
+
62
+ - Obtención de elementos
63
+ ```
64
+ # Get
65
+ df = demeter.get_rtus(element_id=17512, pandas=True)
66
+ print(df)
67
+ ```
68
+ La API define también una excepción especial cuando la llamada al endpoint de Demeter no devuelve el resultado esperado.
69
+ La excepción de denomina "DemeterStatusCodeException" y contiene el código de error HTTP.
70
+ ```
71
+ # Exception treatment
72
+ try:
73
+ df = demeter.get_rtus(element_id=17512, pandas=True)
74
+ except demeter.DemeterStatusCodeException as status_code:
75
+ print('Error {}'.format(status_code))
76
+ ```
77
+ - Por último, se debería hacer un logout en el servidor
78
+ ```
79
+ demeter.logout()
80
+ ```
81
+
82
+
@@ -0,0 +1,66 @@
1
+ # Integrations-PythonAPI
2
+ API Python para facilitar el acceso a los endpoints de la interfaz REST de Demeter
3
+
4
+ La API permite la gestión de grandes cantidades de datos mediante la librería Pandas, siempre y cuando se utilice la siguiente directiva en las llamadas a los métodos:
5
+ ```
6
+ # Pandas = True returns a pandas dataframe instead a json
7
+ ```
8
+
9
+ La forma de usar la API es la siguiente:
10
+
11
+ - Importar los modulos deseados:
12
+ ```
13
+ import demeterpy as demeter
14
+ import demeterapitypes as tp
15
+ import pandas as pd
16
+ import datetime
17
+ import endpoints
18
+ ```
19
+ - Seleccionar el servidor con el cual se quiere comunicar (se puede modificar en todo momento):
20
+ ```
21
+ # Set server
22
+ demeter.set_server(endpoints.Server.MAIN)
23
+ ```
24
+
25
+ - Realizar el login en dicho servidor
26
+ ```
27
+ # Login
28
+ demeter.login('USERNAME', 'PASSWORD')
29
+ ```
30
+
31
+ Una vez seguidos los anteriores pasos, se puede realizar cualquier consulta sobre el sistema.
32
+ Algunas de ellas son:
33
+
34
+ - Búsqueda
35
+ ```
36
+ # Search
37
+ df = demeter.search(text='SAT', element_types=[tp.Element.COUNTER, tp.Element.ANALOG_INPUT, tp.Element.RTU], status=tp.Status.ENABLED, pandas=True)
38
+ print(df)
39
+ ```
40
+
41
+ - Obtención de historicos
42
+ ```
43
+ # Get historics
44
+ df = demeter.get_historics(start_date=datetime.datetime.now(), end_date=datetime.datetime.now(), element_ids=[1000], subtype=tp.AnalogInputHist.subtype, subcode=[tp.AnalogInputHist.subcode], pandas=True)
45
+ print(df)
46
+ ```
47
+
48
+ - Obtención de elementos
49
+ ```
50
+ # Get
51
+ df = demeter.get_rtus(element_id=17512, pandas=True)
52
+ print(df)
53
+ ```
54
+ La API define también una excepción especial cuando la llamada al endpoint de Demeter no devuelve el resultado esperado.
55
+ La excepción de denomina "DemeterStatusCodeException" y contiene el código de error HTTP.
56
+ ```
57
+ # Exception treatment
58
+ try:
59
+ df = demeter.get_rtus(element_id=17512, pandas=True)
60
+ except demeter.DemeterStatusCodeException as status_code:
61
+ print('Error {}'.format(status_code))
62
+ ```
63
+ - Por último, se debería hacer un logout en el servidor
64
+ ```
65
+ demeter.logout()
66
+ ```
@@ -0,0 +1,7 @@
1
+ __version__ = "1.0.0"
2
+
3
+ import hidroconta.types
4
+ import hidroconta.time
5
+ import hidroconta.endpoints
6
+ import hidroconta.hist
7
+ import hidroconta.api
@@ -0,0 +1,232 @@
1
+ import requests as re
2
+ import pandas as pd
3
+ import json
4
+ import hidroconta.types as tp
5
+ import hidroconta.hist as hist
6
+ import hidroconta.endpoints as endpoints
7
+ import hidroconta.time as time
8
+ import datetime
9
+ # For python <3.9, replace list[] with List[] from 'from typing import List'
10
+
11
+ '''
12
+ Allows an easy access to Demeter API from Python and
13
+ implements pandas dataframes compatibility
14
+ '''
15
+
16
+ '''Session cookies stored'''
17
+ __stored_cookies = None
18
+
19
+ POST_HDR = {"Content-Type": "application/json"}
20
+
21
+ # Exception to be thrown when Demeter API returns an error status code
22
+ class DemeterStatusCodeException(Exception):
23
+ pass
24
+
25
+ def set_server(server: endpoints.Server):
26
+ endpoints.set_server(server)
27
+
28
+ def get_server():
29
+ return endpoints.get_server()
30
+
31
+ def login(username: str, password: str):
32
+ global __stored_cookies
33
+
34
+ payload = '{{"username":"{}", "password":"{}"}}'.format(username, password)
35
+
36
+ response = re.post(get_server() + endpoints.DEMETER_LOGIN ,data=payload, headers=POST_HDR)
37
+
38
+ if response.status_code != 200:
39
+ raise DemeterStatusCodeException(response.status_code)
40
+
41
+ cookies = response.cookies.get_dict()
42
+ __stored_cookies = cookies
43
+ return cookies
44
+
45
+ def logout():
46
+ response = re.post(get_server() + endpoints.DEMETER_LOGOUT, cookies=__stored_cookies)
47
+ if response.status_code != 200:
48
+ raise DemeterStatusCodeException(response.status_code)
49
+
50
+ def __get_elements(element: str, element_id: int = None, pandas = False):
51
+ print(get_server() + endpoints.DEMETER_GET + element + ('' if element_id == None else ('/' + str(element_id))))
52
+ response = re.get(get_server() + endpoints.DEMETER_GET + element + ('' if element_id == None else ('/' + str(element_id))), cookies=__stored_cookies)
53
+ if response.status_code != 200:
54
+ raise DemeterStatusCodeException(response.status_code)
55
+ else:
56
+ if pandas:
57
+ data = json.loads(response.text)
58
+ return pd.json_normalize(data)
59
+ else:
60
+ return response.text
61
+
62
+ def search(text:str = None, element_types:list[tp.Element] = None, status:tp.Status = tp.Status.ALL, pandas = False):
63
+
64
+ payload = '{"status":"' + status + '"'
65
+ if(text is not None):
66
+ payload = payload + ',"searchText":"' + text + '"'
67
+ if(element_types is None):
68
+ element_types = [e for e in tp.Element.__dict__.values() if type(e) == str and e != 'demeterapitypes']
69
+ payload = payload + ',"type":' + str(element_types).replace("'", '"')
70
+ payload = payload + '}'
71
+ print(payload)
72
+
73
+ response = re.post(get_server() + endpoints.DEMETER_SEARCH, headers=POST_HDR, data=payload, cookies=__stored_cookies)
74
+ if response.status_code != 200:
75
+ raise DemeterStatusCodeException(response.status_code)
76
+ else:
77
+ if pandas:
78
+ data = json.loads(response.text)
79
+ return pd.json_normalize(data)
80
+ else:
81
+ return response.text
82
+
83
+
84
+ def get_rtus(element_id:int = None, pandas = False):
85
+ return __get_elements('rtus', element_id, pandas)
86
+
87
+ def get_counters(element_id:int = None, pandas = False):
88
+ return __get_elements('counters', element_id, pandas)
89
+
90
+ def get_analog_inputs(element_id:int = None, pandas = False):
91
+ return __get_elements('analogInputs', element_id, pandas)
92
+
93
+ def get_digital_inputs(element_id:int = None, pandas = False):
94
+ return __get_elements('digitalInputs', element_id, pandas)
95
+
96
+ def get_iris_nb(element_id:int = None, pandas = False):
97
+ return __get_elements('iris/nbiot', element_id, pandas)
98
+
99
+ def get_iris_lw(element_id:int = None, pandas = False):
100
+ return __get_elements('iris/lorawan', element_id, pandas)
101
+
102
+ def get_iris_sigfox(element_id:int = None, pandas = False):
103
+ return __get_elements('iris/sigfox', element_id, pandas)
104
+
105
+ def get_iris_gprs(element_id:int = None, pandas = False):
106
+ return __get_elements('iris/gprs', element_id, pandas)
107
+
108
+ def get_installations(element_id:int = None, pandas = False):
109
+ return __get_elements('installations', element_id, pandas)
110
+
111
+ def get_rtus_installation_dict(pandas = False):
112
+ installations = __get_elements('installations', pandas=pandas)
113
+ rtus = __get_elements('rtus', pandas=pandas)
114
+ match_installations = pd.merge(installations, rtus, on='installationId')
115
+ timezones = {}
116
+ for index, match in match_installations.iterrows():
117
+ timezones[match['rtuId']] = match['timeZone']
118
+ return timezones
119
+
120
+ def get_centinel(element_id:int = None, pandas = False):
121
+ return __get_elements('centinel', element_id, pandas)
122
+
123
+ def get_centaurus(element_id:int = None, pandas = False):
124
+ return __get_elements('centaurus', element_id, pandas)
125
+
126
+ def global_update(rtu_id: int, timestamp: datetime.datetime, liters:int):
127
+
128
+ payload = '{"rtuId":' + str(rtu_id) + ',"timestamp":"' + time.strftime_demeter(timestamp) + '","value":' + str(int(liters)) + '}'
129
+ print(payload)
130
+ response = re.put(get_server() + endpoints.DEMETER_UPDATE_COUNTER_GLOBAL ,data=payload, headers=POST_HDR, cookies=__stored_cookies)
131
+ if response.status_code != 200:
132
+ raise DemeterStatusCodeException(response.status_code)
133
+
134
+ def add_historics(rtu_id: int, historics: list[hist.Hist]):
135
+
136
+ hist = '['
137
+ for historic in historics[:-1]:
138
+ hist = hist + '{'
139
+ hist = hist + '"timestamp":"' + str(historic.timestamp) + '",'
140
+ hist = hist + '"subtype":' + str(historic.type.subtype) + ','
141
+ hist = hist + '"subcode":' + str(historic.type.subcode) + ','
142
+ hist = hist + '"value":' + str(historic.value) + ','
143
+ hist = hist + '"position":' + str(historic.position) + ','
144
+ hist = hist + '"expansion":' + str(historic.expansion) + '},'
145
+ historic = historics[-1]
146
+ hist = hist + '{'
147
+ hist = hist + '"timestamp":"' + str(historic.timestamp) + '",'
148
+ hist = hist + '"subtype":' + str(historic.type.subtype) + ','
149
+ hist = hist + '"subcode":' + str(historic.type.subcode) + ','
150
+ hist = hist + '"value":' + str(historic.value) + ','
151
+ hist = hist + '"position":' + str(historic.position) + ','
152
+ hist = hist + '"expansion":' + str(historic.expansion) + '}'
153
+ hist = hist + ']'
154
+
155
+ payload = '{{"rtuId":{}, "historicDataEntities":{}}}'.format(rtu_id, hist)
156
+ print(payload)
157
+ response = re.post(get_server() + endpoints.DEMETER_HISTORICS ,data=payload, headers=POST_HDR, cookies=__stored_cookies)
158
+ if response.status_code != 200:
159
+ raise DemeterStatusCodeException(response.status_code)
160
+
161
+ def get_historics(start_date: datetime.datetime, end_date: datetime.datetime, element_ids: list[int], subtype: int, subcode:list[int] = [], pandas=False):
162
+ start_date = time.strftime_demeter(start_date)
163
+ end_date = time.strftime_demeter(end_date)
164
+ payload = '{{"from":"{}", "until":"{}", "subcode":{}, "subtype":{}, "elementIds":{}}}'.format(start_date, end_date, subcode, subtype, element_ids)
165
+
166
+ response = re.post(get_server() + endpoints.DEMETER_HISTORY_DATA, headers=POST_HDR, data=payload, cookies=__stored_cookies)
167
+ if response.status_code != 200:
168
+ raise DemeterStatusCodeException(response.status_code)
169
+ else:
170
+ if pandas:
171
+ data = json.loads(response.text)
172
+ return pd.json_normalize(data)
173
+ else:
174
+ return response.text
175
+
176
+ def get_minute_consumption(start_date: datetime.datetime, end_date: datetime.datetime, element_ids: list[int], period_value: int, min_interval: bool = True, pandas=False):
177
+ start_date = time.strftime_demeter(start_date)
178
+ end_date = time.strftime_demeter(end_date)
179
+ payload = '{{"from":"{}", "until":"{}", "minInterval":{}, "elementIds":{}, "periodValue":{}}}'.format(start_date, end_date, min_interval, element_ids, period_value)
180
+
181
+ response = re.post(get_server() + endpoints.DEMETER_CONSUMPTION, headers=POST_HDR, data=payload, cookies=__stored_cookies)
182
+ if response.status_code != 200:
183
+ raise DemeterStatusCodeException(response.status_code)
184
+ else:
185
+ if pandas:
186
+ data = json.loads(response.text)
187
+ unfolded = pd.DataFrame(columns=['code', 'timestamp'])
188
+ df = pd.json_normalize(data)
189
+ for ix, row in df.iterrows():
190
+ unfolded_row = row['values']
191
+ unfolded_list = []
192
+ for x in unfolded_row:
193
+ x['code'] = row['series'][0]
194
+ x['values'] = x['values'][0]
195
+ unfolded_list.append(x)
196
+ x['timestamp'] = time.strptime_demeter(x['timestamp'])
197
+ unfolded = pd.concat([unfolded, pd.json_normalize(unfolded_list)])
198
+ return unfolded
199
+ else:
200
+ return response.text
201
+
202
+ def update_analog_input_value(rtu_id:int, position:int, expansion:int, value:int, timestamp:datetime.datetime):
203
+ timestamp = time.strftime_demeter(timestamp)
204
+ payload = '{{"rtuId":{}, "position":{}, "expansion":{}, "value":{}, "timestamp":"{}"}}'.format(rtu_id, position, expansion, value, timestamp)
205
+ print(payload)
206
+ response = re.put(get_server() + endpoints.DEMETER_ANALOG_UPDATE ,data=payload, headers=POST_HDR, cookies=__stored_cookies)
207
+ if response.status_code != 200:
208
+ raise DemeterStatusCodeException(response.status_code)
209
+
210
+ def create_iris_nb(payload:str):
211
+ response = re.post(get_server() + endpoints.DEMETER_IRIS_NB, data=payload, headers=POST_HDR, cookies=__stored_cookies)
212
+ if response.status_code != 201:
213
+ print(response.text)
214
+ raise DemeterStatusCodeException(response.status_code)
215
+
216
+ def delete_iris_nb(elementid:int, confirmation = True):
217
+ if confirmation:
218
+ iris = get_iris_nb(element_id=elementid, pandas=True)
219
+ print('{} será eliminado de {}.'.format(iris['code'].values.tolist()[0], get_server()))
220
+ res = input('Desea continuar (y|n)? ')
221
+ if res.capitalize() == 'Y':
222
+ print('Borrando')
223
+ response = re.delete(get_server() + endpoints.DEMETER_IRIS_NB + '/' + str(elementid), cookies=__stored_cookies)
224
+ if response.status_code != 200:
225
+ raise DemeterStatusCodeException(response.status_code)
226
+ else:
227
+ print('Cancelado')
228
+ return
229
+ else:
230
+ response = re.delete(get_server() + endpoints.DEMETER_IRIS_NB + '/' + str(elementid), cookies=__stored_cookies)
231
+ if response.status_code != 200:
232
+ raise DemeterStatusCodeException(response.status_code)
@@ -0,0 +1,24 @@
1
+ DEMETER_LOGIN = 'login'
2
+ DEMETER_LOGOUT = 'logout'
3
+ DEMETER_GET = ''
4
+ DEMETER_UPDATE_COUNTER_GLOBAL = 'counters/global/update'
5
+ DEMETER_HISTORICS = 'historics'
6
+ DEMETER_HISTORY_DATA = 'history/data'
7
+ DEMETER_ANALOG_UPDATE = 'analogInputs/value/update'
8
+ DEMETER_SEARCH = 'search'
9
+ DEMETER_CONSUMPTION = 'history/consumption/minute/volume'
10
+ DEMETER_IRIS_LORAWAN = 'iris/lorawan'
11
+ DEMETER_IRIS_NB = 'iris/nbiot'
12
+
13
+ class Server(enumerate):
14
+ MAIN = 'https://demeter2.hidroconta.com/Demeter2/v2/'
15
+ TEST = 'https://demeter2-test.hidroconta.com/Demeter2/v2/'
16
+
17
+ __server = Server.MAIN
18
+
19
+ def set_server(server: Server):
20
+ global __server
21
+ __server = server
22
+
23
+ def get_server():
24
+ return __server
@@ -0,0 +1,8 @@
1
+ class Hist:
2
+
3
+ def __init__(self, timestamp = 0, value = 0, position = 0, expansion = 0, type = None):
4
+ self.timestamp=timestamp
5
+ self.value=value
6
+ self.position = position
7
+ self.expansion = expansion
8
+ self.type = type
@@ -0,0 +1,6 @@
1
+ import datetime
2
+ def strftime_demeter(timestamp: datetime.datetime):
3
+ return timestamp.strftime('%d/%m/%Y %H:%M:%S')
4
+
5
+ def strptime_demeter(timestamp: str):
6
+ return datetime.datetime.strptime(timestamp, '%d/%m/%Y %H:%M:%S')
@@ -0,0 +1,25 @@
1
+ class AnalogInputHist:
2
+ subtype = 4
3
+ subcode = 0
4
+
5
+ class CounterGlobalHist:
6
+ subtype = 2
7
+ subcode = 2
8
+
9
+ class Element(enumerate):
10
+ ANALOG_INPUT = 'analogInputs'
11
+ COUNTER = 'counters'
12
+ RTU = 'rtus'
13
+ IRIS = 'iris'
14
+ HYDRANT = 'hydrants'
15
+ VALVE = 'valves'
16
+ DIGITAL_INPUT = 'digitalInputs'
17
+ DIGITAL_OUTPUT = 'digitalOutputs'
18
+ CENTINEL = 'centinels'
19
+ WMBUS_COUNTER = 'wmbusCounters'
20
+ CENTAURUS = 'centaurus'
21
+
22
+ class Status(enumerate):
23
+ ENABLED = 'enabled'
24
+ DISABLED = 'disabled'
25
+ ALL = 'all'
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.1
2
+ Name: hidroconta
3
+ Version: 1.0.0
4
+ Summary: API to easily access Demeter REST API provided by Hidroconta S.A.U.
5
+ Home-page: UNKNOWN
6
+ Author: JavierL
7
+ Author-email: javier.lopez@hidroconta.com
8
+ License: UNKNOWN
9
+ Platform: UNKNOWN
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Integrations-PythonAPI
16
+ API Python para facilitar el acceso a los endpoints de la interfaz REST de Demeter
17
+
18
+ La API permite la gestión de grandes cantidades de datos mediante la librería Pandas, siempre y cuando se utilice la siguiente directiva en las llamadas a los métodos:
19
+ ```
20
+ # Pandas = True returns a pandas dataframe instead a json
21
+ ```
22
+
23
+ La forma de usar la API es la siguiente:
24
+
25
+ - Importar los modulos deseados:
26
+ ```
27
+ import demeterpy as demeter
28
+ import demeterapitypes as tp
29
+ import pandas as pd
30
+ import datetime
31
+ import endpoints
32
+ ```
33
+ - Seleccionar el servidor con el cual se quiere comunicar (se puede modificar en todo momento):
34
+ ```
35
+ # Set server
36
+ demeter.set_server(endpoints.Server.MAIN)
37
+ ```
38
+
39
+ - Realizar el login en dicho servidor
40
+ ```
41
+ # Login
42
+ demeter.login('USERNAME', 'PASSWORD')
43
+ ```
44
+
45
+ Una vez seguidos los anteriores pasos, se puede realizar cualquier consulta sobre el sistema.
46
+ Algunas de ellas son:
47
+
48
+ - Búsqueda
49
+ ```
50
+ # Search
51
+ df = demeter.search(text='SAT', element_types=[tp.Element.COUNTER, tp.Element.ANALOG_INPUT, tp.Element.RTU], status=tp.Status.ENABLED, pandas=True)
52
+ print(df)
53
+ ```
54
+
55
+ - Obtención de historicos
56
+ ```
57
+ # Get historics
58
+ df = demeter.get_historics(start_date=datetime.datetime.now(), end_date=datetime.datetime.now(), element_ids=[1000], subtype=tp.AnalogInputHist.subtype, subcode=[tp.AnalogInputHist.subcode], pandas=True)
59
+ print(df)
60
+ ```
61
+
62
+ - Obtención de elementos
63
+ ```
64
+ # Get
65
+ df = demeter.get_rtus(element_id=17512, pandas=True)
66
+ print(df)
67
+ ```
68
+ La API define también una excepción especial cuando la llamada al endpoint de Demeter no devuelve el resultado esperado.
69
+ La excepción de denomina "DemeterStatusCodeException" y contiene el código de error HTTP.
70
+ ```
71
+ # Exception treatment
72
+ try:
73
+ df = demeter.get_rtus(element_id=17512, pandas=True)
74
+ except demeter.DemeterStatusCodeException as status_code:
75
+ print('Error {}'.format(status_code))
76
+ ```
77
+ - Por último, se debería hacer un logout en el servidor
78
+ ```
79
+ demeter.logout()
80
+ ```
81
+
82
+
@@ -0,0 +1,13 @@
1
+ README.md
2
+ setup.py
3
+ hidroconta/__init__.py
4
+ hidroconta/api.py
5
+ hidroconta/endpoints.py
6
+ hidroconta/hist.py
7
+ hidroconta/time.py
8
+ hidroconta/types.py
9
+ hidroconta.egg-info/PKG-INFO
10
+ hidroconta.egg-info/SOURCES.txt
11
+ hidroconta.egg-info/dependency_links.txt
12
+ hidroconta.egg-info/requires.txt
13
+ hidroconta.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ pandas
2
+ requests
3
+ datetime
@@ -0,0 +1 @@
1
+ hidroconta
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,22 @@
1
+ from setuptools import setup
2
+
3
+ setup(
4
+ name='hidroconta',
5
+ version='1.0.0',
6
+ packages=['hidroconta'],
7
+ install_requires=[
8
+ 'pandas',
9
+ 'requests',
10
+ 'datetime'
11
+ ],
12
+ author='JavierL',
13
+ author_email='javier.lopez@hidroconta.com',
14
+ description='API to easily access Demeter REST API provided by Hidroconta S.A.U.',
15
+ long_description=open('README.md').read(),
16
+ long_description_content_type='text/markdown',
17
+ classifiers=[
18
+ 'Programming Language :: Python :: 3',
19
+ 'License :: OSI Approved :: MIT License',
20
+ 'Operating System :: OS Independent',
21
+ ],
22
+ )