python-sdk-remote 0.0.122__tar.gz → 0.0.125__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.

Potentially problematic release.


This version of python-sdk-remote might be problematic. Click here for more details.

Files changed (21) hide show
  1. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/PKG-INFO +1 -1
  2. python_sdk_remote-0.0.125/README.md +11 -0
  3. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/http_response.py +33 -20
  4. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/utilities.py +30 -8
  5. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote.egg-info/PKG-INFO +1 -1
  6. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/setup.py +1 -1
  7. python_sdk_remote-0.0.122/README.md +0 -27
  8. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/pyproject.toml +0 -0
  9. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/__init__.py +0 -0
  10. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/constants.py +0 -0
  11. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/item.py +0 -0
  12. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/mini_logger.py +0 -0
  13. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/our_object.py +0 -0
  14. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/unified_json.py +0 -0
  15. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/valid_json_versions.py +0 -0
  16. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote/src/validate_environment.py +0 -0
  17. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote.egg-info/SOURCES.txt +0 -0
  18. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote.egg-info/dependency_links.txt +0 -0
  19. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote.egg-info/requires.txt +0 -0
  20. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/python_sdk_remote.egg-info/top_level.txt +0 -0
  21. {python_sdk_remote-0.0.122 → python_sdk_remote-0.0.125}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sdk-remote
3
- Version: 0.0.122
3
+ Version: 0.0.125
4
4
  Summary: PyPI Package for Circles Python SDK Local Python
5
5
  Home-page: https://github.com/circles-zone/python-sdk-remote-python-package
6
6
  Author: Circles
@@ -0,0 +1,11 @@
1
+ # TODO: rewrite with more example
2
+
3
+ In serverless, use this decorator:
4
+ ```py
5
+ from python_sdk_remote.http_response import handler_decorator
6
+ from logger_local.Logger import Logger
7
+ logger = Logger.create_logger(object=your_logger_object)
8
+ @handler_decorator(logger=logger)
9
+ def my_handler(request_parameters: dict) -> dict:
10
+ # here you can use both camelCase and snake_case keys from request_parameters
11
+ ```
@@ -1,9 +1,10 @@
1
- import json
2
1
  import traceback
2
+ from functools import wraps
3
3
  from http import HTTPStatus
4
4
  from typing import Any
5
5
 
6
6
  from .mini_logger import MiniLogger as logger
7
+ from .utilities import camel_to_snake, snake_to_camel, to_dict, to_json
7
8
 
8
9
  HEADERS_KEY = 'headers'
9
10
  AUTHORIZATION_KEY = 'authorization'
@@ -17,7 +18,7 @@ AUTHORIZATION_PREFIX = 'Bearer '
17
18
 
18
19
  def get_payload_dict_from_event(event: dict) -> dict:
19
20
  """Extracts params sent with payload"""
20
- return json.loads(event.get('body') or '{}')
21
+ return to_dict(event.get('body'))
21
22
 
22
23
 
23
24
  def get_path_parameters_dict_from_event(event: dict) -> dict:
@@ -32,13 +33,19 @@ def get_query_string_parameters_from_event(event: dict) -> dict:
32
33
 
33
34
 
34
35
  def get_request_parameters_from_event(event: dict) -> dict:
36
+ """Extracts all params from the event object.
37
+ The order of precedence is: payload > path > query string
38
+ returns a dictionary with all the parameters, with both camelCase and snake_case keys."""
35
39
  all_params = get_payload_dict_from_event(event)
36
40
  all_params.update(get_path_parameters_dict_from_event(event))
37
41
  all_params.update(get_query_string_parameters_from_event(event))
42
+ all_params = {camel_to_snake(key): value for key, value in all_params.items()}
43
+ all_params.update({snake_to_camel(key): value for key, value in all_params.items()})
38
44
  return all_params
39
45
 
46
+
40
47
  # TODO: test
41
- def handler_decorator(handler: callable, logger=logger):
48
+ def handler_decorator(logger):
42
49
  """Decorator for AWS Lambda handler functions. It wraps the handler function with logging and error handling.
43
50
  Usage:
44
51
  from python_sdk_remote.http_response import handler_decorator
@@ -47,22 +54,27 @@ def handler_decorator(handler: callable, logger=logger):
47
54
  def my_handler(request_parameters: dict) -> dict:
48
55
  return {"message": "Hello, World!"}"""
49
56
 
50
- def wrapper(event, context):
51
- handler_response = None
52
- try:
53
- logger.start(object={"event": event, "context": context})
54
- request_parameters = get_request_parameters_from_event(event)
55
- body_result: dict = handler(request_parameters)
56
- handler_response = create_ok_http_response(body_result)
57
- except Exception as e:
58
- handler_response = create_error_http_response(e)
59
- finally:
60
- logger.end(object={"handler_response": handler_response})
61
- return handler_response
57
+ def decorator(handler: callable) -> callable:
58
+ @wraps(handler)
59
+ def wrapper(event, context):
60
+ handler_response = None
61
+ try:
62
+ logger.start(object={"event": event, "context": context})
63
+ request_parameters = get_request_parameters_from_event(event)
64
+ body_result: dict = handler(request_parameters)
65
+ handler_response = create_ok_http_response(body_result)
66
+ except Exception as e:
67
+ handler_response = create_error_http_response(e)
68
+ finally:
69
+ logger.end(object={"handler_response": handler_response})
70
+ return handler_response
71
+
72
+ return wrapper
62
73
 
63
- return wrapper
74
+ return decorator
64
75
 
65
76
 
77
+ # TODO: should we auto detect user_jwt if not provided?
66
78
  def create_authorization_http_headers(user_jwt: str) -> dict:
67
79
  logger.start(object={"user_jwt": user_jwt})
68
80
  authorization_http_headers = {
@@ -107,10 +119,11 @@ def create_error_http_response(exception: Exception, status_code: HTTPStatus = H
107
119
 
108
120
  def create_ok_http_response(body: Any) -> dict:
109
121
  logger.start(object={"body": body})
122
+ # TODO: test sending statusCode/headers/body inside the body
110
123
  ok_http_response = {
111
- "statusCode": HTTPStatus.OK.value,
112
- "headers": create_return_http_headers(),
113
- "body": create_http_body(body)
124
+ "statusCode": body.get("statusCode") or HTTPStatus.OK.value,
125
+ "headers": body.get("headers") or create_return_http_headers(),
126
+ "body": create_http_body(body.get("body") or body)
114
127
  }
115
128
  logger.end(object={"ok_http_response": ok_http_response})
116
129
  return ok_http_response
@@ -121,6 +134,6 @@ def create_http_body(body: Any) -> str:
121
134
  # TODO console.warning() if the body is not a valid camelCase JSON
122
135
  # https://stackoverflow.com/questions/17156078/converting-identifier-naming-between-camelcase-and-underscores-during-json-seria
123
136
  logger.start(object={"body": body})
124
- http_body = json.dumps(body)
137
+ http_body = to_json(body)
125
138
  logger.end(object={"http_body": http_body})
126
139
  return http_body
@@ -1,20 +1,18 @@
1
+ import inspect
1
2
  import json
2
- import jwt
3
- import requests
4
- import re
5
3
  import os
6
4
  import random
5
+ import re
7
6
  from datetime import date, datetime, time, timedelta, timezone
7
+ from functools import lru_cache
8
8
  from urllib.parse import urlparse
9
9
 
10
+ import jwt
11
+ import requests
10
12
  from dotenv import load_dotenv
11
13
  from url_remote.environment_name_enum import EnvironmentName
12
14
 
13
15
  from .mini_logger import MiniLogger as logger
14
- from .http_response import (create_authorization_http_headers, # noqa - used for backwards compatibility
15
- get_user_jwt_from_event,
16
- create_return_http_headers, create_error_http_response, create_ok_http_response,
17
- create_http_body)
18
16
 
19
17
  load_dotenv()
20
18
  # TODO Let's do brainstorming on this
@@ -354,12 +352,13 @@ def obfuscate_log_dict(log_dict: dict) -> dict:
354
352
  if isinstance(value, dict):
355
353
  obfuscated_log_dict[key] = obfuscate_log_dict(value)
356
354
  elif re.search(r'password|secret|token|jwt|e[\-_]?mail|phone|name|address|ssn', key, re.IGNORECASE):
357
- # TODO Maybe we can reveal a small part
355
+ # TODO Maybe we can reveal a small part
358
356
  obfuscated_log_dict[key] = "***"
359
357
  else:
360
358
  obfuscated_log_dict[key] = value
361
359
  return obfuscated_log_dict
362
360
 
361
+
363
362
  # TODO: add tests to the following functions
364
363
 
365
364
  def remove_digits(text: str) -> str:
@@ -415,3 +414,26 @@ def get_ip_v4():
415
414
 
416
415
  def get_ip_v6():
417
416
  return requests.get('https://api.seeip.org/jsonip').json()['ip']
417
+
418
+
419
+ def snake_to_camel(snake_str: str) -> str:
420
+ """Converts snake_case to camelCase."""
421
+ components = snake_str.split('_')
422
+ camel_str = components[0] + ''.join(x.title() for x in components[1:])
423
+ return camel_str
424
+
425
+
426
+ def camel_to_snake(camel_str: str) -> str:
427
+ """Converts camelCase to snake_case."""
428
+ snake_str = re.sub(r'(?<!^)(?=[A-Z])', '_', camel_str).lower()
429
+ return snake_str
430
+
431
+
432
+ @lru_cache(maxsize=64) # don't print the same warning multiple times
433
+ def deprecation_warning(old_name: str, new_name: str):
434
+ warnings_message = f"Please use {old_name} instead of {new_name}."
435
+ try:
436
+ warnings_message += " Called from: " + inspect.stack()[1].filename
437
+ except Exception:
438
+ pass
439
+ logger.warning(warnings_message)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-sdk-remote
3
- Version: 0.0.122
3
+ Version: 0.0.125
4
4
  Summary: PyPI Package for Circles Python SDK Local Python
5
5
  Home-page: https://github.com/circles-zone/python-sdk-remote-python-package
6
6
  Author: Circles
@@ -7,7 +7,7 @@ package_dir = PACKAGE_NAME.replace("-", "_")
7
7
  # python -m build needs pyproject.toml or setup.py
8
8
  setuptools.setup(
9
9
  name=PACKAGE_NAME,
10
- version='0.0.122', # https://pypi.org/project/python-sdk-remote/
10
+ version='0.0.125', # https://pypi.org/project/python-sdk-remote/
11
11
  author="Circles",
12
12
  author_email="info@circlez.ai",
13
13
  description="PyPI Package for Circles Python SDK Local Python",
@@ -1,27 +0,0 @@
1
- # python-sdk-package
2
-
3
- https://github.com/grosser/repo_dependency_graph Ruby, Graph the dependencies of your repositories
4
- https://github.com/thebjorn/pydeps Python
5
-
6
- To create local package and remote package layers (not to create GraphQL and REST-API layers)
7
-
8
- #database Python scripts in /db folder
9
- Please place <table-name>.py in /db<br>
10
- No need for seperate file for _ml table<br>
11
- Please delete the example file if not needed<br>
12
-
13
- # Create the files to create the database schema, tables, view and populate Meta Data and Test Date
14
-
15
- /db/<table-name>.py - CREATE SCHEMA ... CREATE TABLE ... CREATE VIEW ...<br>
16
- /db/<table-name>_insert.py to create records
17
-
18
- # Update the setup.py (i.e.name, version)
19
-
20
- # Please create test directory inside the directory of the project i.e. /<project-name>/tests
21
-
22
- # Update the serverless.yml in the root directory
23
-
24
- provider:
25
- stage: play1
26
-
27
- Update the endpoints in serverless.yml