clear-skies 1.19.10__py3-none-any.whl → 1.19.12__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.

Potentially problematic release.


This version of clear-skies might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: clear-skies
3
- Version: 1.19.10
3
+ Version: 1.19.12
4
4
  Summary: A framework for building backends in the cloud
5
5
  Home-page: https://github.com/cmancone/clearskies
6
6
  License: MIT
@@ -46,7 +46,7 @@ clearskies/autodoc/schema/string.py,sha256=oxZPCxYYhWnNHdbtwD3QuniStbj8XbBBpDTFX
46
46
  clearskies/backends/__init__.py,sha256=3pvJw5dUnrqt7vyeBFjkHbycUEGkEpoYKxZoJwUVZO0,711
47
47
  clearskies/backends/api_backend.py,sha256=vcGYub4G3jLLstTDkMMnZkID9JQz-qHmKNapgde4gSc,8875
48
48
  clearskies/backends/backend.py,sha256=fkL-De0MUdzcS2JG_spSUQZIVL9oRFvaL6SP26JPpcI,7399
49
- clearskies/backends/cursor_backend.py,sha256=B1qpFFr4w459JHgTBMZ16IatMH7urfSBiayZLMj02pk,10804
49
+ clearskies/backends/cursor_backend.py,sha256=owuP4S2dBkEUcPAF5PbZAZZuBXrCoioYtf9ede3Su5Y,11181
50
50
  clearskies/backends/example_backend.py,sha256=jVpv0LZpNUEJGko0XqioLkHmZHbCW6M4YyNvzKlZcDw,1413
51
51
  clearskies/backends/file_backend.py,sha256=tByQdOX1pf6r9-6vRDqOnQ8teRYo0bEWk589qrg598w,1752
52
52
  clearskies/backends/json_backend.py,sha256=uDBqkekQadBm0BMoCVuzSPRB-5SjMTCDSAbuIqqwkF8,180
@@ -55,7 +55,7 @@ clearskies/backends/restful_api_advanced_search_backend.py,sha256=uiR4SEKhLNmczY
55
55
  clearskies/backends/secrets_backend.py,sha256=4lzrgdL_O_pgCT5HknV2gotFgp9GzjQ5_2n0-4H4kvs,2204
56
56
  clearskies/binding_config.py,sha256=bF8LBNEgJacwKCqToAtDqN9hv5omzU7zt_4qB9KPtE0,457
57
57
  clearskies/column_types/__init__.py,sha256=QHEFFd3wRXvaOR7uZk-bpVLlLoTiN3D4S8sBU9rFwCE,4330
58
- clearskies/column_types/audit.py,sha256=klAXnwKjqmNCJqQcBWH5WYPEAZdEblTQTwpcEQAAbqE,8636
58
+ clearskies/column_types/audit.py,sha256=ac9IpcwDRY2JMrfwyH4Zb8Oo9raLcGWqEq9vSAkBxIg,9076
59
59
  clearskies/column_types/belongs_to.py,sha256=tH1tbTOfjifSNuVjO-KbMF7GiUIoLfcDItrrS3TGGM8,11044
60
60
  clearskies/column_types/boolean.py,sha256=1yyM1CUfgD84pPE65c1OP1Qjf_J0Z45hjPrDR51AUkQ,1878
61
61
  clearskies/column_types/category_tree.py,sha256=PgNmzZPyqYS5NADH_QTCxLvDXZFxzv5ESKTkvPrrLXo,9140
@@ -141,7 +141,7 @@ clearskies/handlers/exceptions/not_found.py,sha256=xThOXiMfyYBaI2bhfOhpVoZ_vdw1h
141
141
  clearskies/handlers/get.py,sha256=x9SogDd2ZvIYwv2UkNa_FUmmKMNd9XPadkbnBKbyTGo,6892
142
142
  clearskies/handlers/health_check.py,sha256=m6H3psUql-I7hZao3fsxjrZnCjFJZ1ROTF-41g8Syww,2078
143
143
  clearskies/handlers/input_processing.py,sha256=edtG6NQJZCte0Nq-j7SUMzp6vxgIIbLxeUGscWOALAs,3814
144
- clearskies/handlers/list.py,sha256=Liil791oF9-NjofRV40bNVbhbzF4sM74_efvoDHenqg,25384
144
+ clearskies/handlers/list.py,sha256=RdhvcVA4ZgkdmOHl6iGBC-2jPhjYay0_kFHttmVoq9Q,25466
145
145
  clearskies/handlers/mygrations.py,sha256=4iKpJKooqgNtAURwMl_FgsXUt8OYOaG_TY1OV1llQxY,2759
146
146
  clearskies/handlers/request_method_routing.py,sha256=DgPEz3tgbaUkXHsOriPbIctfSf4Gm4NxfRdVulH91Kg,1636
147
147
  clearskies/handlers/restful_api.py,sha256=1rJ2REX1sTAdbqaRuCclP375agrho4zNNQx6hXGa4nQ,9258
@@ -199,7 +199,7 @@ clearskies/tests/simple_api/models/__init__.py,sha256=nUA0W6fgXw_Bxa9CudkaDkC80t
199
199
  clearskies/tests/simple_api/models/status.py,sha256=PEhPbaQh5qdUNHp8O0gz91LOLENAEBtqSaHxUPXchaM,699
200
200
  clearskies/tests/simple_api/models/user.py,sha256=5_P4Tp1tTdX7PkMJ__epPM5MA7JAeVYGas69vcWloLc,819
201
201
  clearskies/tests/simple_api/users_api.py,sha256=KYXCgEofDxHeRdQK67txN5oYUPvxxmB8JTku7L-apk4,2344
202
- clear_skies-1.19.10.dist-info/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
203
- clear_skies-1.19.10.dist-info/METADATA,sha256=THacV02HYXH5BgFDcRNABBcNWZSLPe7_6XzyuU7n7fc,1367
204
- clear_skies-1.19.10.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
205
- clear_skies-1.19.10.dist-info/RECORD,,
202
+ clear_skies-1.19.12.dist-info/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
203
+ clear_skies-1.19.12.dist-info/METADATA,sha256=E8zPgCzyP7hE3uR9vkWkREkvPRvHU-zAQ0StlsoXZvM,1367
204
+ clear_skies-1.19.12.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
205
+ clear_skies-1.19.12.dist-info/RECORD,,
@@ -138,6 +138,17 @@ class CursorBackend(Backend):
138
138
  next_page_data["start"] = int(start) + int(limit)
139
139
  return records
140
140
 
141
+ def group_by_clause(self, group_by):
142
+ if not group_by:
143
+ return ""
144
+ escape = self._column_escape_character()
145
+ if "." not in group_by:
146
+ return f" GROUP BY {escape}{group_by}{escape}"
147
+ parts = group_by.split(".", 1)
148
+ table = parts[0]
149
+ column = parts[1]
150
+ return f" GROUP BY {escape}{table}{escape}.{escape}{column}{escape}"
151
+
141
152
  def as_sql(self, configuration):
142
153
  escape = self._column_escape_character()
143
154
  [wheres, parameters] = self._conditions_as_wheres_and_parameters(configuration["wheres"])
@@ -162,11 +173,7 @@ class CursorBackend(Backend):
162
173
  order_by = " ORDER BY " + ", ".join(sort_parts)
163
174
  else:
164
175
  order_by = ""
165
- group_by = (
166
- f" GROUP BY {escape}" + configuration["group_by_column"] + escape
167
- if configuration["group_by_column"]
168
- else ""
169
- )
176
+ group_by = self.group_by_clause(configuration["group_by_column"])
170
177
  limit = ""
171
178
  if configuration["limit"]:
172
179
  start = 0
@@ -195,7 +202,10 @@ class CursorBackend(Backend):
195
202
  if not configuration["group_by_column"]:
196
203
  query = f"SELECT COUNT(*) AS count FROM {table_name}{joins}{wheres}"
197
204
  else:
198
- query = f'SELECT COUNT(SELECT 1 FROM {table_name}{joins}{wheres} GROUP BY {escape}{configuration["group_by_column"]}{escape}) AS count'
205
+ group_by = self.group_by_clause(configuration["group_by_column"])
206
+ query = (
207
+ f"SELECT COUNT(*) AS count FROM (SELECT 1 FROM {table_name}{joins}{wheres}{group_by}) AS count_inner"
208
+ )
199
209
  return [query, parameters]
200
210
 
201
211
  def _conditions_as_wheres_and_parameters(self, conditions):
@@ -134,6 +134,8 @@ class Audit(has_many.HasMany):
134
134
  **create_data,
135
135
  **parent_columns[key].to_json(model),
136
136
  }
137
+ if key in mask_columns and key in create_data:
138
+ create_data[key] = "****"
137
139
  self.record(model, "create", data=create_data)
138
140
  return
139
141
 
@@ -157,7 +159,7 @@ class Audit(has_many.HasMany):
157
159
  **to_data,
158
160
  **parent_columns[column].to_json(model),
159
161
  }
160
- if column in mask_columns:
162
+ if column in mask_columns and column in to_data:
161
163
  to_data[column] = "****"
162
164
  from_data[column] = "****"
163
165
  if not from_data and not to_data:
@@ -176,15 +178,28 @@ class Audit(has_many.HasMany):
176
178
  super().post_delete(model)
177
179
  exclude_columns = self.config("exclude_columns")
178
180
  parent_columns = self.parent_columns
181
+ mask_columns = self.config("mask_columns")
182
+
183
+ final_data = {}
184
+ for key in model._data.keys():
185
+ if key in exclude_columns:
186
+ continue
187
+ final_data = {
188
+ **final_data,
189
+ **parent_columns[key].to_json(model),
190
+ }
191
+
192
+ for key in mask_columns:
193
+ if key not in final_data:
194
+ continue
195
+ final_data[key] = "****"
179
196
 
180
197
  self.child_models.create(
181
198
  {
182
199
  "class": self.config("parent_class_name"),
183
200
  "resource_id": model.get(self.config("parent_id_column_name")),
184
201
  "action": "delete",
185
- "data": {
186
- key: parent_columns[key].to_json(model) for key in model._data.keys() if key not in exclude_columns
187
- },
202
+ "data": final_data,
188
203
  }
189
204
  )
190
205
 
@@ -255,11 +255,13 @@ class List(Base):
255
255
 
256
256
  # common checks for group_by and default_sort_column
257
257
  for config_name in ["group_by", "default_sort_column"]:
258
- if (
259
- config_name in configuration
260
- and configuration[config_name]
261
- and configuration[config_name] not in self._columns
262
- ):
258
+ value = configuration.get(config_name)
259
+ if not value:
260
+ continue
261
+ # we're being lazy for now and not checking complicated values
262
+ if "." in value:
263
+ continue
264
+ if value not in self._columns:
263
265
  raise ValueError(
264
266
  f"{error_prefix} '{config_name}' references column named {column_name} "
265
267
  + f"but this column does not exist for model '{model_class_name}'"