scdata 1.2.6__tar.gz → 1.3.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.
Files changed (87) hide show
  1. {scdata-1.2.6/scdata.egg-info → scdata-1.3.0}/PKG-INFO +3 -2
  2. {scdata-1.2.6 → scdata-1.3.0}/requirements.txt +3 -2
  3. {scdata-1.2.6 → scdata-1.3.0}/scdata/__init__.py +1 -1
  4. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/device.py +42 -1
  5. {scdata-1.2.6 → scdata-1.3.0}/scdata/io/device_file.py +7 -5
  6. {scdata-1.2.6 → scdata-1.3.0}/scdata/models/models.py +5 -3
  7. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/date.py +7 -7
  8. {scdata-1.2.6 → scdata-1.3.0/scdata.egg-info}/PKG-INFO +3 -2
  9. {scdata-1.2.6 → scdata-1.3.0}/scdata.egg-info/requires.txt +2 -1
  10. {scdata-1.2.6 → scdata-1.3.0}/setup.py +1 -1
  11. {scdata-1.2.6 → scdata-1.3.0}/LICENSE +0 -0
  12. {scdata-1.2.6 → scdata-1.3.0}/MANIFEST.in +0 -0
  13. {scdata-1.2.6 → scdata-1.3.0}/README.md +0 -0
  14. {scdata-1.2.6 → scdata-1.3.0}/scdata/_config/__init__.py +0 -0
  15. {scdata-1.2.6 → scdata-1.3.0}/scdata/_config/config.py +0 -0
  16. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/__init__.py +0 -0
  17. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/plot/__init__.py +0 -0
  18. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/__init__.py +0 -0
  19. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/alphasense.py +0 -0
  20. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/baseline.py +0 -0
  21. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/error_codes.py +0 -0
  22. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/formulae.py +0 -0
  23. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/geoseries.py +0 -0
  24. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/params.py +0 -0
  25. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/regression.py +0 -0
  26. {scdata-1.2.6 → scdata-1.3.0}/scdata/device/process/timeseries.py +0 -0
  27. {scdata-1.2.6 → scdata-1.3.0}/scdata/io/__init__.py +0 -0
  28. {scdata-1.2.6 → scdata-1.3.0}/scdata/io/device_api.py +0 -0
  29. {scdata-1.2.6 → scdata-1.3.0}/scdata/io/model.py +0 -0
  30. {scdata-1.2.6 → scdata-1.3.0}/scdata/models/__init__.py +0 -0
  31. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/__init__.py +0 -0
  32. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/checks/__init__.py +0 -0
  33. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/checks/checks.py +0 -0
  34. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/dispersion/__init__.py +0 -0
  35. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/dispersion/dispersion.py +0 -0
  36. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/export/__init__.py +0 -0
  37. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/export/templates/sc_template.html +0 -0
  38. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/export/to_file.py +0 -0
  39. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/__init__.py +0 -0
  40. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/box_plot.py +0 -0
  41. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/heatmap_iplot.py +0 -0
  42. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/heatmap_plot.py +0 -0
  43. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/maps.py +0 -0
  44. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/plot_tools.py +0 -0
  45. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/scatter_dispersion_grid.py +0 -0
  46. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/scatter_iplot.py +0 -0
  47. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/scatter_plot.py +0 -0
  48. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/target_diagram.py +0 -0
  49. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_dendrogram.py +0 -0
  50. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_dispersion_grid.py +0 -0
  51. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_dispersion_plot.py +0 -0
  52. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_dispersion_uplot.py +0 -0
  53. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_iplot.py +0 -0
  54. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_plot.py +0 -0
  55. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_scatter.py +0 -0
  56. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/plot/ts_uplot.py +0 -0
  57. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/test.py +0 -0
  58. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/tools/__init__.py +0 -0
  59. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/tools/combine.py +0 -0
  60. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/tools/history.py +0 -0
  61. {scdata-1.2.6 → scdata-1.3.0}/scdata/test/tools/prepare.py +0 -0
  62. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/__init__.py +0 -0
  63. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/cleaning.py +0 -0
  64. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/custom_logger.py +0 -0
  65. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/dictmerge.py +0 -0
  66. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/find.py +0 -0
  67. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/gets.py +0 -0
  68. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/interim/example.csv +0 -0
  69. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/interim/geodata.csv +0 -0
  70. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/lazy.py +0 -0
  71. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/location.py +0 -0
  72. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/report.py +0 -0
  73. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/stats.py +0 -0
  74. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/units.py +0 -0
  75. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/uploads/example_upload_1.json +0 -0
  76. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/uploads/example_zenodo_upload.yaml +0 -0
  77. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/uploads/report.pdf +0 -0
  78. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/url_check.py +0 -0
  79. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/zenodo.py +0 -0
  80. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/zenodo_templates/README.md +0 -0
  81. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/zenodo_templates/template_zenodo_dataset.json +0 -0
  82. {scdata-1.2.6 → scdata-1.3.0}/scdata/tools/zenodo_templates/template_zenodo_publication.json +0 -0
  83. {scdata-1.2.6 → scdata-1.3.0}/scdata.egg-info/SOURCES.txt +0 -0
  84. {scdata-1.2.6 → scdata-1.3.0}/scdata.egg-info/dependency_links.txt +0 -0
  85. {scdata-1.2.6 → scdata-1.3.0}/scdata.egg-info/not-zip-safe +0 -0
  86. {scdata-1.2.6 → scdata-1.3.0}/scdata.egg-info/top_level.txt +0 -0
  87. {scdata-1.2.6 → scdata-1.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scdata
3
- Version: 1.2.6
3
+ Version: 1.3.0
4
4
  Summary: Analysis of sensors and time series data
5
5
  Home-page: https://github.com/fablabbcn/smartcitizen-data
6
6
  Author: oscgonfer
@@ -24,7 +24,6 @@ Requires-Dist: folium~=0.12.1
24
24
  Requires-Dist: geopy~=1.21.0
25
25
  Requires-Dist: Jinja2~=3.1.2
26
26
  Requires-Dist: matplotlib
27
- Requires-Dist: numpy~=1.25.2
28
27
  Requires-Dist: pandas~=2.2.2
29
28
  Requires-Dist: pydantic
30
29
  Requires-Dist: pytest
@@ -38,6 +37,8 @@ Requires-Dist: termcolor==1.1.0
38
37
  Requires-Dist: tqdm~=4.50.2
39
38
  Requires-Dist: timezonefinder~=6.1.9
40
39
  Requires-Dist: urllib3
40
+ Requires-Dist: boto3
41
+ Requires-Dist: awswrangler
41
42
  Dynamic: author
42
43
  Dynamic: classifier
43
44
  Dynamic: description
@@ -9,7 +9,6 @@ geopy~=1.21.0
9
9
  # TODO To be updated?
10
10
  Jinja2~=3.1.2
11
11
  matplotlib
12
- numpy~=1.25.2
13
12
  pandas~=2.2.2
14
13
  pydantic
15
14
  pytest
@@ -23,4 +22,6 @@ smartcitizen-connector
23
22
  termcolor==1.1.0
24
23
  tqdm~=4.50.2
25
24
  timezonefinder~=6.1.9
26
- urllib3
25
+ urllib3
26
+ boto3
27
+ awswrangler
@@ -3,4 +3,4 @@ from .device import Device
3
3
  from .test import Test
4
4
  from .models import Source, TestOptions, DeviceOptions, APIParams, FileParams, CSVParams
5
5
 
6
- __version__ = '1.2.6'
6
+ __version__ = '1.3.0'
@@ -23,6 +23,19 @@ from pydantic_core import ValidationError
23
23
  from typing import Optional, List
24
24
  from json import dumps
25
25
 
26
+ import os
27
+ from io import StringIO
28
+
29
+ try:
30
+ import awswrangler as wr
31
+ except ModuleNotFoundError:
32
+ boto_available = False
33
+ pass
34
+ else:
35
+ boto_available = True
36
+
37
+ if boto_available: import boto3
38
+
26
39
  from timezonefinder import TimezoneFinder
27
40
  tf = TimezoneFinder()
28
41
 
@@ -287,6 +300,7 @@ class Device(BaseModel):
287
300
  resample = self.options.resample
288
301
  limit = self.options.limit
289
302
  channels = self.options.channels
303
+ dateformat = self.options.dateformat
290
304
  cached_data = DataFrame()
291
305
 
292
306
  # Only case where cache makes sense
@@ -334,7 +348,8 @@ class Device(BaseModel):
334
348
  max_date = max_date,
335
349
  frequency = frequency,
336
350
  clean_na = clean_na,
337
- resample = resample)
351
+ resample = resample,
352
+ dateformat = dateformat)
338
353
 
339
354
  # In principle this links both dataframes as they are unmutable
340
355
  self.data = self.handler.data
@@ -706,3 +721,29 @@ class Device(BaseModel):
706
721
 
707
722
  if post_ok: logger.info(f"Postprocessing posted for device {self.paramsParsed.id}")
708
723
  return post_ok
724
+
725
+ def backup(self, format='parquet', mode='append'):
726
+ if self.data.empty:
727
+ logger.error("Device data empty")
728
+ return False
729
+
730
+ if format == 'parquet':
731
+ if boto_available:
732
+ self.data['TIME']=self.data.index
733
+ target_path = f"s3://{os.environ['S3_DATA_BUCKET']}/devices/{self.id}/data/"
734
+ response = wr.s3.to_parquet(df=self.data, path=target_path, dataset=True, mode=mode)
735
+
736
+ return response
737
+
738
+ def backup_load(self, format='parquet'):
739
+ if format == 'parquet':
740
+ if boto_available:
741
+ session = boto3.Session(aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
742
+ aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
743
+ region_name=os.environ['AWS_REGION'])
744
+ s3_url = f"s3://{os.environ['S3_DATA_BUCKET']}/devices/{self.id}/data/"
745
+ self.data = wr.s3.read_parquet(s3_url, boto3_session=session, dataset=True)
746
+ self.data.set_index('TIME', inplace=True)
747
+ self.data.sort_index(inplace=True)
748
+
749
+ return s3_url
@@ -57,7 +57,9 @@ class CSVHandler:
57
57
  skiprows=self.params.header_skip,
58
58
  sep=self.params.separator,
59
59
  tzaware=self.params.tzaware,
60
- resample=kwargs['resample']
60
+ resample=kwargs['resample'],
61
+ dateformat=kwargs['dateformat']
62
+ # TODO Pandas read_csv kwargs???
61
63
  )
62
64
 
63
65
  return self.data
@@ -94,7 +96,7 @@ def export_csv_file(path, file_name, df, forced_overwrite=False):
94
96
  return False
95
97
  return True
96
98
 
97
- def read_csv_file(path, timezone, frequency=None, clean_na=None, index_name='', skiprows=None, sep=',', encoding='utf-8', tzaware=True, resample=True):
99
+ def read_csv_file(path, timezone, frequency=None, clean_na=None, index_name='', skiprows=None, sep=',', encoding='utf-8', tzaware=True, resample=True, dateformat=None):
98
100
  """
99
101
  Reads a csv file and adds cleaning, localisation and resampling and puts it into a pandas dataframe
100
102
  Parameters
@@ -127,9 +129,9 @@ def read_csv_file(path, timezone, frequency=None, clean_na=None, index_name='',
127
129
  """
128
130
 
129
131
  # Read pandas dataframe
130
-
131
132
  df = read_csv(path, skiprows=skiprows, sep=sep,
132
- encoding=encoding, encoding_errors='ignore')
133
+ encoding=encoding, encoding_errors='ignore',
134
+ date_format=dateformat)
133
135
 
134
136
  flag_found = False
135
137
  if type(index_name) == str:
@@ -156,7 +158,7 @@ def read_csv_file(path, timezone, frequency=None, clean_na=None, index_name='',
156
158
  return None
157
159
 
158
160
  # Set index
159
- df.index = localise_date(df.index, timezone, tzaware=tzaware)
161
+ df.index = localise_date(df.index, timezone, tzaware=tzaware, dateformat=dateformat)
160
162
  # Remove duplicates
161
163
  df = df[~df.index.duplicated(keep='first')]
162
164
 
@@ -1,5 +1,5 @@
1
1
  from pydantic import BaseModel
2
- from typing import Optional, List
2
+ from typing import Optional, List, Any
3
3
  from datetime import datetime
4
4
 
5
5
  class TestOptions(BaseModel):
@@ -28,10 +28,10 @@ class Source(BaseModel):
28
28
  handler: str = 'SCDevice'
29
29
 
30
30
  class APIParams(BaseModel):
31
- id: int
31
+ id: Any
32
32
 
33
33
  class FileParams(BaseModel):
34
- id: int # To be compatible with API id
34
+ id: Any # To be compatible with API id
35
35
  path: str
36
36
 
37
37
  class CSVParams(FileParams):
@@ -40,6 +40,7 @@ class CSVParams(FileParams):
40
40
  separator: Optional[str] = ','
41
41
  tzaware: Optional[bool] = True
42
42
  timezone: Optional[str] = "UTC"
43
+ date_format: Optional[str] = None
43
44
 
44
45
  class DeviceOptions(BaseModel):
45
46
  clean_na: Optional[bool] = None
@@ -51,6 +52,7 @@ class DeviceOptions(BaseModel):
51
52
  channels: Optional[List[str]] = []
52
53
  convert_units: Optional[bool] = True
53
54
  convert_names: Optional[bool] = True
55
+ dateformat: Optional[str] = None
54
56
 
55
57
  class Blueprint(BaseModel):
56
58
  meta: dict = dict()
@@ -1,6 +1,6 @@
1
1
  from pandas import to_datetime
2
2
 
3
- def localise_date(date, timezone, tzaware=True):
3
+ def localise_date(date, timezone, tzaware=True, dateformat = None):
4
4
  """
5
5
  Localises a date if it's tzinfo is None, otherwise converts it to it.
6
6
  If the timestamp is tz-aware, converts it as well
@@ -13,16 +13,16 @@ def localise_date(date, timezone, tzaware=True):
13
13
  Returns
14
14
  -------
15
15
  The date converted to 'UTC' and localised based on the timezone
16
- """
16
+ """
17
17
  if date is not None:
18
18
  # Per default, we consider that timestamps are tz-aware or UTC.
19
19
  # If not, preprocessing should be done to get there
20
- result_date = to_datetime(date, utc = tzaware)
21
- if result_date.tzinfo is not None:
20
+ result_date = to_datetime(date, utc = tzaware, format=dateformat)
21
+ if result_date.tzinfo is not None:
22
22
  result_date = result_date.tz_convert(timezone)
23
23
  else:
24
24
  result_date = result_date.tz_localize(timezone)
25
- else:
25
+ else:
26
26
  result_date = None
27
27
 
28
28
  return result_date
@@ -37,10 +37,10 @@ def find_dates(dataframe):
37
37
  Returns
38
38
  -------
39
39
  Rounded down first day, rounded up last day and number of days between them
40
- """
40
+ """
41
41
 
42
42
  range_days = (dataframe.index.max()-dataframe.index.min()).days
43
43
  min_date_df = dataframe.index.min().floor('D')
44
44
  max_date_df = dataframe.index.max().ceil('D')
45
-
45
+
46
46
  return min_date_df, max_date_df, range_days
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scdata
3
- Version: 1.2.6
3
+ Version: 1.3.0
4
4
  Summary: Analysis of sensors and time series data
5
5
  Home-page: https://github.com/fablabbcn/smartcitizen-data
6
6
  Author: oscgonfer
@@ -24,7 +24,6 @@ Requires-Dist: folium~=0.12.1
24
24
  Requires-Dist: geopy~=1.21.0
25
25
  Requires-Dist: Jinja2~=3.1.2
26
26
  Requires-Dist: matplotlib
27
- Requires-Dist: numpy~=1.25.2
28
27
  Requires-Dist: pandas~=2.2.2
29
28
  Requires-Dist: pydantic
30
29
  Requires-Dist: pytest
@@ -38,6 +37,8 @@ Requires-Dist: termcolor==1.1.0
38
37
  Requires-Dist: tqdm~=4.50.2
39
38
  Requires-Dist: timezonefinder~=6.1.9
40
39
  Requires-Dist: urllib3
40
+ Requires-Dist: boto3
41
+ Requires-Dist: awswrangler
41
42
  Dynamic: author
42
43
  Dynamic: classifier
43
44
  Dynamic: description
@@ -4,7 +4,6 @@ folium~=0.12.1
4
4
  geopy~=1.21.0
5
5
  Jinja2~=3.1.2
6
6
  matplotlib
7
- numpy~=1.25.2
8
7
  pandas~=2.2.2
9
8
  pydantic
10
9
  pytest
@@ -18,3 +17,5 @@ termcolor==1.1.0
18
17
  tqdm~=4.50.2
19
18
  timezonefinder~=6.1.9
20
19
  urllib3
20
+ boto3
21
+ awswrangler
@@ -19,7 +19,7 @@ REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]
19
19
 
20
20
  setup(
21
21
  name='scdata',
22
- version='1.2.6',
22
+ version='1.3.0',
23
23
  description='Analysis of sensors and time series data',
24
24
  author='oscgonfer',
25
25
  license='GNU-GPL3.0',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes