velocity-python 0.0.30__py3-none-any.whl → 0.0.32__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 velocity-python might be problematic. Click here for more details.

velocity/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.0.30"
1
+ __version__ = version = "0.0.32"
2
2
 
3
3
  from . import aws
4
4
  from . import db
velocity/aws/__init__.py CHANGED
@@ -1,22 +1,18 @@
1
1
  import os
2
2
  import requests
3
3
 
4
- DEBUG = (os.environ.get('ENV') != 'production') \
5
- or (os.environ.get('DEBUG') == 'Y')
4
+ DEBUG = (os.environ.get("ENV") != "production") or (os.environ.get("DEBUG") == "Y")
6
5
 
7
6
 
8
7
  # This is helpful for running HTTPS clients on lambda.
9
- if os.path.exists('/opt/python/ca-certificates.crt'):
10
- os.environ["REQUESTS_CA_BUNDLE"] = '/opt/python/ca-certificates.crt'
8
+ if os.path.exists("/opt/python/ca-certificates.crt"):
9
+ os.environ["REQUESTS_CA_BUNDLE"] = "/opt/python/ca-certificates.crt"
11
10
 
12
11
 
13
12
  class AWS(object):
14
13
  # Get AWS EC2 Instance ID. Must run this from the EC2 instance itself to get the ID
15
14
  @staticmethod
16
15
  def instance_id(cls):
17
- response = requests.get(
18
- 'http://169.254.169.254/latest/meta-data/instance-id')
16
+ response = requests.get("http://169.254.169.254/latest/meta-data/instance-id")
19
17
  instance_id = response.text
20
18
  return instance_id
21
-
22
-
@@ -1,17 +1,20 @@
1
- from velocity.misc.format import to_json
2
1
  import sys
3
2
  import traceback
3
+ from typing import Any, Dict, List, Optional, Union
4
+ from velocity.misc.format import to_json
4
5
  from support.app import DEBUG
5
6
 
6
7
 
7
- variants = ["success", "error", "warning", "info"]
8
+ class Response:
9
+ """Class to manage and structure HTTP responses with various actions and custom headers."""
8
10
 
11
+ VALID_VARIANTS = {"success", "error", "warning", "info"}
9
12
 
10
- class Response:
11
13
  def __init__(self):
12
- self.actions = []
13
- self.body = {"actions": self.actions}
14
- self.raw = {
14
+ """Initialize the Response object with default status, headers, and an empty actions list."""
15
+ self.actions: List[Dict[str, Any]] = []
16
+ self.body: Dict[str, Any] = {"actions": self.actions}
17
+ self.raw: Dict[str, Any] = {
15
18
  "statusCode": 200,
16
19
  "body": "{}",
17
20
  "headers": {
@@ -22,118 +25,266 @@ class Response:
22
25
  },
23
26
  }
24
27
 
25
- def render(self):
28
+ def render(self) -> Dict[str, Any]:
29
+ """
30
+ Finalize the response body as JSON and return the complete response dictionary.
31
+
32
+ Returns:
33
+ Dict[str, Any]: The complete HTTP response with headers, status code, and JSON body.
34
+ """
26
35
  self.raw["body"] = to_json(self.body)
27
36
  return self.raw
28
37
 
29
- def alert(self, message, title="Notification"):
38
+ def alert(self, message: str, title: str = "Notification") -> "Response":
39
+ """
40
+ Add an alert action to the response.
41
+
42
+ Args:
43
+ message (str): The alert message.
44
+ title (str): Title for the alert. Defaults to "Notification".
45
+
46
+ Returns:
47
+ Response: The current Response object, allowing method chaining.
48
+ """
30
49
  self.actions.append(
31
50
  {
32
51
  "action": "alert",
33
- "payload": {
34
- "title": title,
35
- "message": message,
36
- },
52
+ "payload": {"title": title, "message": message},
37
53
  }
38
54
  )
39
55
  return self
40
56
 
41
- def toast(self, message, variant="success"):
57
+ def toast(self, message: str, variant: str = "success") -> "Response":
58
+ """
59
+ Add a toast notification action to the response with a specified variant.
60
+
61
+ Args:
62
+ message (str): The message to display in the toast.
63
+ variant (str): The style variant of the toast (e.g., "success", "error"). Must be one of VALID_VARIANTS.
64
+
65
+ Raises:
66
+ ValueError: If the variant is not one of VALID_VARIANTS.
67
+
68
+ Returns:
69
+ Response: The current Response object, allowing method chaining.
70
+ """
42
71
  variant = variant.lower()
43
- if variant not in variants:
44
- raise Exception(f"Notistack variant {variant} not in {variants}")
72
+ if variant not in self.VALID_VARIANTS:
73
+ raise ValueError(
74
+ f"Notistack variant '{variant}' not in {self.VALID_VARIANTS}"
75
+ )
45
76
  self.actions.append(
46
77
  {
47
78
  "action": "toast",
48
- "payload": {
49
- "options": {
50
- "variant": variant,
51
- },
52
- "message": message,
53
- },
79
+ "payload": {"options": {"variant": variant}, "message": message},
54
80
  }
55
81
  )
56
82
  return self
57
83
 
58
- def load_object(self, payload):
84
+ def load_object(self, payload: Dict[str, Any]) -> "Response":
85
+ """
86
+ Add a load-object action to the response with a specified payload.
87
+
88
+ Args:
89
+ payload (Dict[str, Any]): The data to load into the response.
90
+
91
+ Returns:
92
+ Response: The current Response object, allowing method chaining.
93
+ """
59
94
  self.actions.append({"action": "load-object", "payload": payload})
60
95
  return self
61
96
 
62
- def update_store(self, payload):
97
+ def update_store(self, payload: Dict[str, Any]) -> "Response":
98
+ """
99
+ Add an update-store action to the response with a specified payload.
100
+
101
+ Args:
102
+ payload (Dict[str, Any]): The data to update the store with.
103
+
104
+ Returns:
105
+ Response: The current Response object, allowing method chaining.
106
+ """
63
107
  self.actions.append({"action": "update-store", "payload": payload})
64
108
  return self
65
109
 
66
- def file_download(self, payload):
110
+ def file_download(self, payload: Dict[str, Any]) -> "Response":
111
+ """
112
+ Add a file-download action to the response with a specified payload.
113
+
114
+ Args:
115
+ payload (Dict[str, Any]): The data for file download details.
116
+
117
+ Returns:
118
+ Response: The current Response object, allowing method chaining.
119
+ """
67
120
  self.actions.append({"action": "file-download", "payload": payload})
68
121
  return self
69
122
 
70
- def status(self, code=None):
71
- if code:
123
+ def status(self, code: Optional[int] = None) -> int:
124
+ """
125
+ Get or set the status code of the response.
126
+
127
+ Args:
128
+ code (Optional[int]): The HTTP status code to set. If None, returns the current status code.
129
+
130
+ Returns:
131
+ int: The current status code.
132
+ """
133
+ if code is not None:
72
134
  self.raw["statusCode"] = int(code)
73
135
  return self.raw["statusCode"]
74
136
 
75
- def headers(self, headers=None):
137
+ def headers(self, headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
138
+ """
139
+ Get or update the headers of the response.
140
+
141
+ Args:
142
+ headers (Optional[Dict[str, str]]): A dictionary of headers to add or update.
143
+
144
+ Returns:
145
+ Dict[str, str]: The current headers after updates.
146
+ """
76
147
  if headers:
77
- new = {}
78
- for key in headers.keys():
79
- new["-".join(w.capitalize() for w in key.split("-"))] = headers[key]
80
- self.raw["headers"].update(new)
148
+ formatted_headers = {
149
+ self._format_header_key(k): v for k, v in headers.items()
150
+ }
151
+ self.raw["headers"].update(formatted_headers)
81
152
  return self.raw["headers"]
82
153
 
83
- def set_status(self, code):
154
+ def set_status(self, code: int) -> "Response":
155
+ """
156
+ Set the HTTP status code of the response.
157
+
158
+ Args:
159
+ code (int): The status code to set.
160
+
161
+ Returns:
162
+ Response: The current Response object, allowing method chaining.
163
+ """
84
164
  self.status(code)
85
165
  return self
86
166
 
87
- def set_headers(self, headers):
167
+ def set_headers(self, headers: Dict[str, str]) -> "Response":
168
+ """
169
+ Set custom headers for the response.
170
+
171
+ Args:
172
+ headers (Dict[str, str]): The headers to add or update.
173
+
174
+ Returns:
175
+ Response: The current Response object, allowing method chaining.
176
+ """
88
177
  self.headers(headers)
89
178
  return self
90
179
 
91
- def set_body(self, body):
180
+ def set_body(self, body: Dict[str, Any]) -> "Response":
181
+ """
182
+ Update the body of the response with new data.
183
+
184
+ Args:
185
+ body (Dict[str, Any]): The body data to update.
186
+
187
+ Returns:
188
+ Response: The current Response object, allowing method chaining.
189
+ """
92
190
  self.body.update(body)
93
191
  return self
94
192
 
95
- def exception(self):
96
- t, v, tb = sys.exc_info()
193
+ def exception(self) -> None:
194
+ """
195
+ Capture and format the current exception details and set a 500 status code.
196
+ Includes traceback information if DEBUG mode is enabled.
197
+ """
198
+ exc_type, exc_value, tb = sys.exc_info()
97
199
  self.set_status(500)
98
200
  self.set_body(
99
201
  {
100
202
  "python_exception": {
101
- "type": str(t),
102
- "value": str(v),
203
+ "type": str(exc_type),
204
+ "value": str(exc_value),
103
205
  "traceback": traceback.format_exc() if DEBUG else None,
104
206
  "tb": traceback.format_tb(tb) if DEBUG else None,
105
207
  }
106
208
  }
107
209
  )
108
210
 
109
- def console(self, message, title="Notification"):
211
+ def console(self, message: str, title: str = "Notification") -> "Response":
212
+ """
213
+ Add a console log action to the response.
214
+
215
+ Args:
216
+ message (str): The console message.
217
+ title (str): Title for the console message. Defaults to "Notification".
218
+
219
+ Returns:
220
+ Response: The current Response object, allowing method chaining.
221
+ """
110
222
  self.actions.append(
111
223
  {
112
224
  "action": "console",
113
- "payload": {
114
- "title": title,
115
- "message": message,
116
- },
225
+ "payload": {"title": title, "message": message},
117
226
  }
118
227
  )
119
228
  return self
120
229
 
121
- def redirect(self, location):
230
+ def redirect(self, location: str) -> "Response":
231
+ """
232
+ Add a redirect action to the response with the target location.
233
+
234
+ Args:
235
+ location (str): The URL to redirect to.
236
+
237
+ Returns:
238
+ Response: The current Response object, allowing method chaining.
239
+ """
122
240
  self.actions.append({"action": "redirect", "payload": {"location": location}})
123
241
  return self
124
242
 
125
- def signout(self, location):
126
- self.actions.append(
127
- {
128
- "action": "signout",
129
- }
130
- )
243
+ def signout(self) -> "Response":
244
+ """
245
+ Add a signout action to the response.
246
+
247
+ Returns:
248
+ Response: The current Response object, allowing method chaining.
249
+ """
250
+ self.actions.append({"action": "signout"})
131
251
  return self
132
252
 
133
- def set_table(self, payload):
253
+ def set_table(self, payload: Dict[str, Any]) -> "Response":
254
+ """
255
+ Add a set-table action to the response with the specified payload.
256
+
257
+ Args:
258
+ payload (Dict[str, Any]): The table data to set.
259
+
260
+ Returns:
261
+ Response: The current Response object, allowing method chaining.
262
+ """
134
263
  self.actions.append({"action": "set-table", "payload": payload})
135
264
  return self
136
265
 
137
- def set_repo(self, payload):
266
+ def set_repo(self, payload: Dict[str, Any]) -> "Response":
267
+ """
268
+ Add a set-repo action to the response with the specified payload.
269
+
270
+ Args:
271
+ payload (Dict[str, Any]): The repository data to set.
272
+
273
+ Returns:
274
+ Response: The current Response object, allowing method chaining.
275
+ """
138
276
  self.actions.append({"action": "set-repo", "payload": payload})
139
277
  return self
278
+
279
+ @staticmethod
280
+ def _format_header_key(key: str) -> str:
281
+ """
282
+ Format HTTP headers to be in a title-cased format.
283
+
284
+ Args:
285
+ key (str): The header key to format.
286
+
287
+ Returns:
288
+ str: The formatted header key.
289
+ """
290
+ return "-".join(word.capitalize() for word in key.split("-"))
@@ -1,10 +1,12 @@
1
1
  from velocity.db import exceptions
2
2
  from velocity.db.core.decorators import return_default
3
3
 
4
+
4
5
  class Column(object):
5
6
  """
6
7
  Represents a column in a database table.
7
8
  """
9
+
8
10
  def __init__(self, table, name):
9
11
  """
10
12
  Initializes a column object with the specified table and name.
@@ -12,11 +14,11 @@ class Column(object):
12
14
  Args:
13
15
  table (table): The table object that the column belongs to.
14
16
  name (str): The name of the column.
15
-
17
+
16
18
  Raises:
17
19
  Exception: If the table parameter is not of type 'table'.
18
20
  """
19
- if isinstance(table,str):
21
+ if isinstance(table, str):
20
22
  raise Exception("column table parameter must be a `table` class.")
21
23
  self.tx = table.tx
22
24
  self.sql = table.tx.engine.sql
@@ -39,13 +41,13 @@ class Column(object):
39
41
  NULL OK: %s
40
42
  Foreign Key: %s
41
43
  """ % (
42
- self.table.name,
43
- self.name,
44
- self.exists(),
45
- self.py_type,
46
- self.sql_type,
47
- self.is_nullok,
48
- self.foreign_key_to
44
+ self.table.name,
45
+ self.name,
46
+ self.exists(),
47
+ self.py_type,
48
+ self.sql_type,
49
+ self.is_nullok,
50
+ self.foreign_key_to,
49
51
  )
50
52
 
51
53
  @property
@@ -55,7 +57,7 @@ class Column(object):
55
57
 
56
58
  Returns:
57
59
  dict: A dictionary containing information about the column.
58
-
60
+
59
61
  Raises:
60
62
  DbColumnMissingError: If the column does not exist in the database.
61
63
  """
@@ -72,7 +74,7 @@ class Column(object):
72
74
 
73
75
  Returns:
74
76
  dict: A dictionary containing information about the foreign key constraint.
75
-
77
+
76
78
  Raises:
77
79
  DbColumnMissingError: If the column does not exist in the database.
78
80
  """
@@ -89,12 +91,14 @@ class Column(object):
89
91
 
90
92
  Returns:
91
93
  str: The name of the referenced table and column in the format 'referenced_table_name.referenced_column_name'.
92
-
94
+
93
95
  Raises:
94
96
  DbColumnMissingError: If the column does not exist in the database.
95
97
  """
96
98
  try:
97
- return "{referenced_table_name}.{referenced_column_name}".format(**self.foreign_key_info)
99
+ return "{referenced_table_name}.{referenced_column_name}".format(
100
+ **self.foreign_key_info
101
+ )
98
102
  except exceptions.DbColumnMissingError:
99
103
  return None
100
104
 
@@ -105,12 +109,12 @@ class Column(object):
105
109
 
106
110
  Returns:
107
111
  str: The name of the referenced table.
108
-
112
+
109
113
  Raises:
110
114
  DbColumnMissingError: If the column does not exist in the database.
111
115
  """
112
116
  try:
113
- return self.foreign_key_info['referenced_table_name']
117
+ return self.foreign_key_info["referenced_table_name"]
114
118
  except exceptions.DbColumnMissingError:
115
119
  return None
116
120
 
@@ -167,7 +171,7 @@ class Column(object):
167
171
  self.name = name
168
172
 
169
173
  @return_default([])
170
- def distinct(self, order='asc', qty=None):
174
+ def distinct(self, order="asc", qty=None):
171
175
  """
172
176
  Retrieves distinct values from the column.
173
177
 
@@ -178,7 +182,12 @@ class Column(object):
178
182
  Returns:
179
183
  list: A list of distinct values from the column.
180
184
  """
181
- sql, vals = self.sql.select(columns="distinct {}".format(self.name), table=self.table.name, orderby="{} {}".format(self.name,order), qty=qty)
185
+ sql, vals = self.sql.select(
186
+ columns="distinct {}".format(self.name),
187
+ table=self.table.name,
188
+ orderby="{} {}".format(self.name, order),
189
+ qty=qty,
190
+ )
182
191
  return self.tx.execute(sql, vals).as_simple_list().all()
183
192
 
184
193
  def max(self, where=None):
@@ -190,13 +199,15 @@ class Column(object):
190
199
 
191
200
  Returns:
192
201
  int: The maximum value from the column.
193
-
202
+
194
203
  Raises:
195
204
  DbTableMissingError: If the table does not exist in the database.
196
205
  DbColumnMissingError: If the column does not exist in the database.
197
206
  """
198
207
  try:
199
- sql, vals = self.sql.select(columns="max({})".format(self.name), table=self.table.name, where=where)
208
+ sql, vals = self.sql.select(
209
+ columns="max({})".format(self.name), table=self.table.name, where=where
210
+ )
200
211
  return self.tx.execute(sql, vals).scalar()
201
- except (exceptions.DbTableMissingError,exceptions.DbColumnMissingError):
212
+ except (exceptions.DbTableMissingError, exceptions.DbColumnMissingError):
202
213
  return 0
@@ -1,8 +1,8 @@
1
1
  class Database(object):
2
-
2
+
3
3
  def __init__(self, tx, name=None):
4
4
  self.tx = tx
5
- self.name = name or self.tx.engine.config['database']
5
+ self.name = name or self.tx.engine.config["database"]
6
6
  self.sql = tx.engine.sql
7
7
 
8
8
  def __str__(self):
@@ -12,10 +12,10 @@ class Database(object):
12
12
  (db exists) %s
13
13
  Tables: %s
14
14
  """ % (
15
- self.tx.engine.sql.server,
16
- self.name,
17
- self.exists(),
18
- len(self.tables)
15
+ self.tx.engine.sql.server,
16
+ self.name,
17
+ self.exists(),
18
+ len(self.tables),
19
19
  )
20
20
 
21
21
  def __enter__(self):
@@ -28,7 +28,7 @@ class Database(object):
28
28
  def close(self):
29
29
  try:
30
30
  self._cursor.close()
31
- #print("*** database('{}').cursor.close()".format(self.name))
31
+ # print("*** database('{}').cursor.close()".format(self.name))
32
32
  except AttributeError:
33
33
  pass
34
34
 
@@ -37,7 +37,7 @@ class Database(object):
37
37
  try:
38
38
  return self._cursor
39
39
  except AttributeError:
40
- #print("*** database('{}').cursor.open()".format(self.name))
40
+ # print("*** database('{}').cursor.open()".format(self.name))
41
41
  self._cursor = self.tx.cursor()
42
42
  return self._cursor
43
43
 
@@ -57,7 +57,7 @@ class Database(object):
57
57
  @property
58
58
  def tables(self):
59
59
  sql, vals = self.sql.tables()
60
- result = self.tx.execute(sql ,vals, cursor=self.cursor)
60
+ result = self.tx.execute(sql, vals, cursor=self.cursor)
61
61
  return ["%s.%s" % x for x in result.as_tuple()]
62
62
 
63
63
  def reindex(self):