diff options
Diffstat (limited to 'python-nichelper.spec')
| -rw-r--r-- | python-nichelper.spec | 1560 |
1 files changed, 1560 insertions, 0 deletions
diff --git a/python-nichelper.spec b/python-nichelper.spec new file mode 100644 index 0000000..b74e65a --- /dev/null +++ b/python-nichelper.spec @@ -0,0 +1,1560 @@ +%global _empty_manifest_terminate_build 0 +Name: python-nicHelper +Version: 0.0.110 +Release: 1 +Summary: some helper functions from nic's gist +License: Apache Software License 2.0 +URL: https://github.com/thanakijwanavit/nicHelper/tree/master/ +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/01/fc/e36415d54c56659dc705ccd39e2c1821c4d0d5e9afc4d6f79bd45e93c27f/nicHelper-0.0.110.tar.gz +BuildArch: noarch + +Requires: python3-requests +Requires: python3-boto3 +Requires: python3-ujson +Requires: python3-Pillow +Requires: python3-genson +Requires: python3-pyyaml +Requires: python3-dpath +Requires: python3-pytest +Requires: python3-beartype +Requires: python3-dataclasses-jsonschema +Requires: python3-cachetools +Requires: python3-pycryptodome + +%description +# Helpers +> various helpers from nic gist + + +full docs here +https://thanakijwanavit.github.io/nicHelper/ + +``` +from nicHelper.wrappers import add_method +``` + +## Install + +`pip install nicHelper` + +# How to use + +## method module + +### add method to a class + +``` +class A: + pass + +@add_method(A) +def printHello(self): + print('hello') + +A().printHello() +``` + + hello + + +This is equivalent to +``` +class A: + def printHello(self): + print('hello') + +``` + +## Dict utilities + +### Pretty print a dict +print only the first 10 characters of dict key, works with deep nested dict + +``` +from nicHelper.dictUtil import printDict +printDict({'key':'sjfhdkljhafsdlkjhdfaslkjhkljfadshklhfa', 'nestedKey':{'nestedKey2':'938023840843', 'nested3':{'nested4':'hello'}}}) +``` + + key : sjfhdkljha + nestedKey + nestedKey2 : 9380238408 + nested3 + nested4 : hello + + +### change all nested datetime object into timestamp for json compatibility + +``` +from nicHelper.dictUtil import filterDt +from datetime import datetime + +filterDt({'time': {'time2':datetime.now()}, 'hello': 'world'}) +``` + + + + + {'time': {'time2': 1615312774.297602}, 'hello': 'world'} + + + +## Exception module + +``` +from nicHelper.exception import errorString +try: + error +except: + print(f'error is \n{errorString()}') +``` + + error is + Traceback (most recent call last): + File "<ipython-input-6-86083feec525>", line 3, in <module> + error + NameError: name 'error' is not defined + + + +## Image utils + +``` +from nicHelper.images import imageFromUrl, imageToS3, showImgS3, resizeImage +from s3bz.s3bz import S3 +``` + +``` +## test variables +key = 'testCat.png' +path = '/tmp/testCat.png' +bucket = 'villa-remove-bg-small-output' +url = 'https://sites.google.com/site/funnycatmeawww/_/rsrc/1422326075261/home/6997052-funny-cat.jpg?height=675&width=1200' +``` + +### Resize images + +``` +resizeImage(url, 400) +``` + + + + + + + + + + +### load image from url + +``` +img = imageFromUrl(url) +type(img) +``` + + + + + PIL.JpegImagePlugin.JpegImageFile + + + +### save Image to S3 + +``` +imageToS3(img, bucket, key) +S3.exist(key,bucket) +``` + + saving image to villa-remove-bg-small-output/testCat.png + + + + + + True + + + +### display image from s3 + +``` +## full test +showImgS3(bucket, key) +``` + + + + + + + +## Secrets + +``` +from nicHelper.secrets import getSecret +secret = getSecret(name="removeBg", region='ap-southeast-1') +``` + +## Shorten link with tenxor.sh + +``` +from nicHelper.shortenLink import shorten +``` + +``` +shorten('https://www.youtube.com/watch?v=fp85zRg2cwg') +``` + + + + + 'https://tenxor.sh/d3Cp' + + + +## Schema + +``` +from nicHelper.schema import getSchemaPath, validateUrl, typeMapJsonSchema +``` + +### Get schema from path + +``` +testSchema = 'https://gist.githubusercontent.com/thanakijwanavit/e2720d091ae0cef710a49b57c0c9cd4c/raw/ed2d322eac4900ee0f95b431d0f9067a40f3e0f0/squirrelOpenApiV0.0.3.yaml' +path = 'components/schemas/Location' +getSchemaPath(testSchema, path) +``` + + + + + {'type': 'object', + 'required': ['id', + 'type', + 'street_address', + 'city', + 'state', + 'zip', + 'capacity', + 'status'], + 'properties': {'id': {'type': 'string', 'format': 'uuid'}, + 'type': {'type': 'string', 'enum': ['pick up', 'drop off', 'overnight']}, + 'street_address': {'type': 'string'}, + 'city': {'type': 'string'}, + 'state': {'type': 'string', + 'pattern': '^(?:(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY]))$'}, + 'zip': {'type': 'string', 'pattern': '(^\\d{5}$)|(^\\d{5}-\\d{4}$)'}, + 'status': {'type': 'string', 'enum': ['open', 'in use']}, + 'created': {'type': 'string', 'format': 'date-time'}, + 'modified': {'type': 'string', 'format': 'date-time'}}} + + + +### Validate Url + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +input_ = {'iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +validateUrl(url, input_) +``` + + + + + namespace(cprcode=123, iprcode=4, oprCode='123') + + + +### Convert type to comply with json schema + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/dev-manual/inventory/inventory.yaml' +inv = { + 'iprcode': '0000009', + 'brcode': '1000', + 'ib_cf_qty': '50', + 'new_ib_vs_stock_cv': '27', + 'onlineflag': True + } +typeMapJsonSchema(url, input_=inv) +``` + + typesDict is: {'iprcode': <class 'int'>, 'brcode': <class 'int'>, 'ib_cf_qty': <class 'int'>, 'new_ib_vs_stock_cv': <class 'int'>, 'onlineflag': <class 'bool'>} + + + + + + {'iprcode': 9, + 'brcode': 1000, + 'ib_cf_qty': 50, + 'new_ib_vs_stock_cv': 27, + 'onlineflag': True} + + + +## Pynamodb + +``` +from nicHelper.pynamodb import SchemaAttribute, SuperModel, createData, getData, updateData +from pynamodb.attributes import Attribute, UnicodeAttribute, NumberAttribute +from beartype import beartype +from awsSchema.apigateway import Event, Response +``` + +### SchemaAttribute +a class which automatically parse and check data against json schema + +```SchemaAttribute(*args, **kwargs) :: Attribute``` + +### Supermodel +a class which add some functionalities on top of the standard pynamodb model + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +from typing import Any +class TestModel(SuperModel): + class Meta: + table_name="colab-test-sensitive-column" + region = 'ap-southeast-1' + data = SchemaAttribute(schemaUrl = schemaUrl, null=True) + phoneHash = UnicodeAttribute(hash_key=True) + + + # Overrides + def pullOutKeys(self)->None: + self.phoneHash = str(self.data.get('phoneHash') or self.data.get('iprcode') or self.data.get('id') ) + + @beartype + def toDict(self)->dict: + return self.data + + @classmethod + @beartype + def fromDict(cls, inputDict:dict)->Any: + return cls(data=inputDict) + + @beartype + def update(self,inputDict:dict)->None: + self.data.update(inputDict) +``` + +``` +from nicHelper.exception import errorString +try: + test = TestModel.fromDict({'iprcode': 4, 'cprcode': 123 , 'oprCode': '123', 'orderId': 123}) + test.save() +except Exception as e: + print(e) + print(errorString()) + + +next(TestModel.query('1')) +``` + + + + + {"data": {"type": "pick up", "street_address": "123", "id": "123", "city": "sth", "state": "CA", "zip": "23523", "capacity": 5, "status": "open"}} + + + +### createData +create a new row of data + +``` +## lambda create function +def create (event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + r = createData(event2, hashKeyName='phoneHash', mainClass=TestModel) + if r.get('statusCode') != 200: return r + r2 = next(TestModel.query(body['phoneHash']), None) + if not r2: return Response.returnError('st wrong with saving, saving but didnt go through') + return Response.returnSuccess(r2) +``` + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +item = next(TestModel.queryId('123'), None) +print('existing item is :',item) +# delete item if exist +if item: + print(item.delete()) +create(event) +``` + + existing item is : {"creationTime": 1615893836.030621, "data": {"phoneHash": "123", "iprcode": 5, "cprcode": 123, "oprCode": "1234", "id": "123"}, "lastEdited": 1615894057.181481, "phoneHash": "123"} + {'ConsumedCapacity': {'CapacityUnits': 1.0, 'TableName': 'colab-test-sensitive-column'}} + + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### getData + +``` +def lambdaGet(event, *args): + query = Event.parseBody(event) + if 'key' not in query: return Response.returnError(f'missing key') + return getData(query['key'], TestModel) +``` + +``` +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +create(event) + +lambdaGet(Event.getInput({'key': '123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### updateData + +``` +def update(event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + hashKeyname = 'id' + return updateData(event2, hashKeyName=hashKeyname, mainClass=TestModel) +``` + +``` +r = create(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '123'})) +r = update(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '1234'})) +lambdaGet(Event.getInput({'key':'123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":5,"cprcode":123,"oprCode":"1234","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +## Timer + +``` +from nicHelper.timer import Timer +``` + +### setting start timer + +``` +timer = Timer() +timer.t0 +``` + + + + + datetime.datetime(2021, 4, 16, 6, 57, 1, 236974) + + + +### print the time between starting time and current time + +``` +timer.print_time() +``` + + fuction took :3.422775 s + + + + + + 3.422775 + + + +### print the time between starting time and current time and reset the timer + +``` +timer.print_reset() +``` + + function took :0.376299 s + + + + + + 0.376299 + + + + +%package -n python3-nicHelper +Summary: some helper functions from nic's gist +Provides: python-nicHelper +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-nicHelper +# Helpers +> various helpers from nic gist + + +full docs here +https://thanakijwanavit.github.io/nicHelper/ + +``` +from nicHelper.wrappers import add_method +``` + +## Install + +`pip install nicHelper` + +# How to use + +## method module + +### add method to a class + +``` +class A: + pass + +@add_method(A) +def printHello(self): + print('hello') + +A().printHello() +``` + + hello + + +This is equivalent to +``` +class A: + def printHello(self): + print('hello') + +``` + +## Dict utilities + +### Pretty print a dict +print only the first 10 characters of dict key, works with deep nested dict + +``` +from nicHelper.dictUtil import printDict +printDict({'key':'sjfhdkljhafsdlkjhdfaslkjhkljfadshklhfa', 'nestedKey':{'nestedKey2':'938023840843', 'nested3':{'nested4':'hello'}}}) +``` + + key : sjfhdkljha + nestedKey + nestedKey2 : 9380238408 + nested3 + nested4 : hello + + +### change all nested datetime object into timestamp for json compatibility + +``` +from nicHelper.dictUtil import filterDt +from datetime import datetime + +filterDt({'time': {'time2':datetime.now()}, 'hello': 'world'}) +``` + + + + + {'time': {'time2': 1615312774.297602}, 'hello': 'world'} + + + +## Exception module + +``` +from nicHelper.exception import errorString +try: + error +except: + print(f'error is \n{errorString()}') +``` + + error is + Traceback (most recent call last): + File "<ipython-input-6-86083feec525>", line 3, in <module> + error + NameError: name 'error' is not defined + + + +## Image utils + +``` +from nicHelper.images import imageFromUrl, imageToS3, showImgS3, resizeImage +from s3bz.s3bz import S3 +``` + +``` +## test variables +key = 'testCat.png' +path = '/tmp/testCat.png' +bucket = 'villa-remove-bg-small-output' +url = 'https://sites.google.com/site/funnycatmeawww/_/rsrc/1422326075261/home/6997052-funny-cat.jpg?height=675&width=1200' +``` + +### Resize images + +``` +resizeImage(url, 400) +``` + + + + + + + + + + +### load image from url + +``` +img = imageFromUrl(url) +type(img) +``` + + + + + PIL.JpegImagePlugin.JpegImageFile + + + +### save Image to S3 + +``` +imageToS3(img, bucket, key) +S3.exist(key,bucket) +``` + + saving image to villa-remove-bg-small-output/testCat.png + + + + + + True + + + +### display image from s3 + +``` +## full test +showImgS3(bucket, key) +``` + + + + + + + +## Secrets + +``` +from nicHelper.secrets import getSecret +secret = getSecret(name="removeBg", region='ap-southeast-1') +``` + +## Shorten link with tenxor.sh + +``` +from nicHelper.shortenLink import shorten +``` + +``` +shorten('https://www.youtube.com/watch?v=fp85zRg2cwg') +``` + + + + + 'https://tenxor.sh/d3Cp' + + + +## Schema + +``` +from nicHelper.schema import getSchemaPath, validateUrl, typeMapJsonSchema +``` + +### Get schema from path + +``` +testSchema = 'https://gist.githubusercontent.com/thanakijwanavit/e2720d091ae0cef710a49b57c0c9cd4c/raw/ed2d322eac4900ee0f95b431d0f9067a40f3e0f0/squirrelOpenApiV0.0.3.yaml' +path = 'components/schemas/Location' +getSchemaPath(testSchema, path) +``` + + + + + {'type': 'object', + 'required': ['id', + 'type', + 'street_address', + 'city', + 'state', + 'zip', + 'capacity', + 'status'], + 'properties': {'id': {'type': 'string', 'format': 'uuid'}, + 'type': {'type': 'string', 'enum': ['pick up', 'drop off', 'overnight']}, + 'street_address': {'type': 'string'}, + 'city': {'type': 'string'}, + 'state': {'type': 'string', + 'pattern': '^(?:(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY]))$'}, + 'zip': {'type': 'string', 'pattern': '(^\\d{5}$)|(^\\d{5}-\\d{4}$)'}, + 'status': {'type': 'string', 'enum': ['open', 'in use']}, + 'created': {'type': 'string', 'format': 'date-time'}, + 'modified': {'type': 'string', 'format': 'date-time'}}} + + + +### Validate Url + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +input_ = {'iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +validateUrl(url, input_) +``` + + + + + namespace(cprcode=123, iprcode=4, oprCode='123') + + + +### Convert type to comply with json schema + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/dev-manual/inventory/inventory.yaml' +inv = { + 'iprcode': '0000009', + 'brcode': '1000', + 'ib_cf_qty': '50', + 'new_ib_vs_stock_cv': '27', + 'onlineflag': True + } +typeMapJsonSchema(url, input_=inv) +``` + + typesDict is: {'iprcode': <class 'int'>, 'brcode': <class 'int'>, 'ib_cf_qty': <class 'int'>, 'new_ib_vs_stock_cv': <class 'int'>, 'onlineflag': <class 'bool'>} + + + + + + {'iprcode': 9, + 'brcode': 1000, + 'ib_cf_qty': 50, + 'new_ib_vs_stock_cv': 27, + 'onlineflag': True} + + + +## Pynamodb + +``` +from nicHelper.pynamodb import SchemaAttribute, SuperModel, createData, getData, updateData +from pynamodb.attributes import Attribute, UnicodeAttribute, NumberAttribute +from beartype import beartype +from awsSchema.apigateway import Event, Response +``` + +### SchemaAttribute +a class which automatically parse and check data against json schema + +```SchemaAttribute(*args, **kwargs) :: Attribute``` + +### Supermodel +a class which add some functionalities on top of the standard pynamodb model + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +from typing import Any +class TestModel(SuperModel): + class Meta: + table_name="colab-test-sensitive-column" + region = 'ap-southeast-1' + data = SchemaAttribute(schemaUrl = schemaUrl, null=True) + phoneHash = UnicodeAttribute(hash_key=True) + + + # Overrides + def pullOutKeys(self)->None: + self.phoneHash = str(self.data.get('phoneHash') or self.data.get('iprcode') or self.data.get('id') ) + + @beartype + def toDict(self)->dict: + return self.data + + @classmethod + @beartype + def fromDict(cls, inputDict:dict)->Any: + return cls(data=inputDict) + + @beartype + def update(self,inputDict:dict)->None: + self.data.update(inputDict) +``` + +``` +from nicHelper.exception import errorString +try: + test = TestModel.fromDict({'iprcode': 4, 'cprcode': 123 , 'oprCode': '123', 'orderId': 123}) + test.save() +except Exception as e: + print(e) + print(errorString()) + + +next(TestModel.query('1')) +``` + + + + + {"data": {"type": "pick up", "street_address": "123", "id": "123", "city": "sth", "state": "CA", "zip": "23523", "capacity": 5, "status": "open"}} + + + +### createData +create a new row of data + +``` +## lambda create function +def create (event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + r = createData(event2, hashKeyName='phoneHash', mainClass=TestModel) + if r.get('statusCode') != 200: return r + r2 = next(TestModel.query(body['phoneHash']), None) + if not r2: return Response.returnError('st wrong with saving, saving but didnt go through') + return Response.returnSuccess(r2) +``` + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +item = next(TestModel.queryId('123'), None) +print('existing item is :',item) +# delete item if exist +if item: + print(item.delete()) +create(event) +``` + + existing item is : {"creationTime": 1615893836.030621, "data": {"phoneHash": "123", "iprcode": 5, "cprcode": 123, "oprCode": "1234", "id": "123"}, "lastEdited": 1615894057.181481, "phoneHash": "123"} + {'ConsumedCapacity': {'CapacityUnits': 1.0, 'TableName': 'colab-test-sensitive-column'}} + + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### getData + +``` +def lambdaGet(event, *args): + query = Event.parseBody(event) + if 'key' not in query: return Response.returnError(f'missing key') + return getData(query['key'], TestModel) +``` + +``` +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +create(event) + +lambdaGet(Event.getInput({'key': '123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### updateData + +``` +def update(event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + hashKeyname = 'id' + return updateData(event2, hashKeyName=hashKeyname, mainClass=TestModel) +``` + +``` +r = create(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '123'})) +r = update(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '1234'})) +lambdaGet(Event.getInput({'key':'123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":5,"cprcode":123,"oprCode":"1234","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +## Timer + +``` +from nicHelper.timer import Timer +``` + +### setting start timer + +``` +timer = Timer() +timer.t0 +``` + + + + + datetime.datetime(2021, 4, 16, 6, 57, 1, 236974) + + + +### print the time between starting time and current time + +``` +timer.print_time() +``` + + fuction took :3.422775 s + + + + + + 3.422775 + + + +### print the time between starting time and current time and reset the timer + +``` +timer.print_reset() +``` + + function took :0.376299 s + + + + + + 0.376299 + + + + +%package help +Summary: Development documents and examples for nicHelper +Provides: python3-nicHelper-doc +%description help +# Helpers +> various helpers from nic gist + + +full docs here +https://thanakijwanavit.github.io/nicHelper/ + +``` +from nicHelper.wrappers import add_method +``` + +## Install + +`pip install nicHelper` + +# How to use + +## method module + +### add method to a class + +``` +class A: + pass + +@add_method(A) +def printHello(self): + print('hello') + +A().printHello() +``` + + hello + + +This is equivalent to +``` +class A: + def printHello(self): + print('hello') + +``` + +## Dict utilities + +### Pretty print a dict +print only the first 10 characters of dict key, works with deep nested dict + +``` +from nicHelper.dictUtil import printDict +printDict({'key':'sjfhdkljhafsdlkjhdfaslkjhkljfadshklhfa', 'nestedKey':{'nestedKey2':'938023840843', 'nested3':{'nested4':'hello'}}}) +``` + + key : sjfhdkljha + nestedKey + nestedKey2 : 9380238408 + nested3 + nested4 : hello + + +### change all nested datetime object into timestamp for json compatibility + +``` +from nicHelper.dictUtil import filterDt +from datetime import datetime + +filterDt({'time': {'time2':datetime.now()}, 'hello': 'world'}) +``` + + + + + {'time': {'time2': 1615312774.297602}, 'hello': 'world'} + + + +## Exception module + +``` +from nicHelper.exception import errorString +try: + error +except: + print(f'error is \n{errorString()}') +``` + + error is + Traceback (most recent call last): + File "<ipython-input-6-86083feec525>", line 3, in <module> + error + NameError: name 'error' is not defined + + + +## Image utils + +``` +from nicHelper.images import imageFromUrl, imageToS3, showImgS3, resizeImage +from s3bz.s3bz import S3 +``` + +``` +## test variables +key = 'testCat.png' +path = '/tmp/testCat.png' +bucket = 'villa-remove-bg-small-output' +url = 'https://sites.google.com/site/funnycatmeawww/_/rsrc/1422326075261/home/6997052-funny-cat.jpg?height=675&width=1200' +``` + +### Resize images + +``` +resizeImage(url, 400) +``` + + + + + + + + + + +### load image from url + +``` +img = imageFromUrl(url) +type(img) +``` + + + + + PIL.JpegImagePlugin.JpegImageFile + + + +### save Image to S3 + +``` +imageToS3(img, bucket, key) +S3.exist(key,bucket) +``` + + saving image to villa-remove-bg-small-output/testCat.png + + + + + + True + + + +### display image from s3 + +``` +## full test +showImgS3(bucket, key) +``` + + + + + + + +## Secrets + +``` +from nicHelper.secrets import getSecret +secret = getSecret(name="removeBg", region='ap-southeast-1') +``` + +## Shorten link with tenxor.sh + +``` +from nicHelper.shortenLink import shorten +``` + +``` +shorten('https://www.youtube.com/watch?v=fp85zRg2cwg') +``` + + + + + 'https://tenxor.sh/d3Cp' + + + +## Schema + +``` +from nicHelper.schema import getSchemaPath, validateUrl, typeMapJsonSchema +``` + +### Get schema from path + +``` +testSchema = 'https://gist.githubusercontent.com/thanakijwanavit/e2720d091ae0cef710a49b57c0c9cd4c/raw/ed2d322eac4900ee0f95b431d0f9067a40f3e0f0/squirrelOpenApiV0.0.3.yaml' +path = 'components/schemas/Location' +getSchemaPath(testSchema, path) +``` + + + + + {'type': 'object', + 'required': ['id', + 'type', + 'street_address', + 'city', + 'state', + 'zip', + 'capacity', + 'status'], + 'properties': {'id': {'type': 'string', 'format': 'uuid'}, + 'type': {'type': 'string', 'enum': ['pick up', 'drop off', 'overnight']}, + 'street_address': {'type': 'string'}, + 'city': {'type': 'string'}, + 'state': {'type': 'string', + 'pattern': '^(?:(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY]))$'}, + 'zip': {'type': 'string', 'pattern': '(^\\d{5}$)|(^\\d{5}-\\d{4}$)'}, + 'status': {'type': 'string', 'enum': ['open', 'in use']}, + 'created': {'type': 'string', 'format': 'date-time'}, + 'modified': {'type': 'string', 'format': 'date-time'}}} + + + +### Validate Url + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +input_ = {'iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +validateUrl(url, input_) +``` + + + + + namespace(cprcode=123, iprcode=4, oprCode='123') + + + +### Convert type to comply with json schema + +``` +url = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/dev-manual/inventory/inventory.yaml' +inv = { + 'iprcode': '0000009', + 'brcode': '1000', + 'ib_cf_qty': '50', + 'new_ib_vs_stock_cv': '27', + 'onlineflag': True + } +typeMapJsonSchema(url, input_=inv) +``` + + typesDict is: {'iprcode': <class 'int'>, 'brcode': <class 'int'>, 'ib_cf_qty': <class 'int'>, 'new_ib_vs_stock_cv': <class 'int'>, 'onlineflag': <class 'bool'>} + + + + + + {'iprcode': 9, + 'brcode': 1000, + 'ib_cf_qty': 50, + 'new_ib_vs_stock_cv': 27, + 'onlineflag': True} + + + +## Pynamodb + +``` +from nicHelper.pynamodb import SchemaAttribute, SuperModel, createData, getData, updateData +from pynamodb.attributes import Attribute, UnicodeAttribute, NumberAttribute +from beartype import beartype +from awsSchema.apigateway import Event, Response +``` + +### SchemaAttribute +a class which automatically parse and check data against json schema + +```SchemaAttribute(*args, **kwargs) :: Attribute``` + +### Supermodel +a class which add some functionalities on top of the standard pynamodb model + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +from typing import Any +class TestModel(SuperModel): + class Meta: + table_name="colab-test-sensitive-column" + region = 'ap-southeast-1' + data = SchemaAttribute(schemaUrl = schemaUrl, null=True) + phoneHash = UnicodeAttribute(hash_key=True) + + + # Overrides + def pullOutKeys(self)->None: + self.phoneHash = str(self.data.get('phoneHash') or self.data.get('iprcode') or self.data.get('id') ) + + @beartype + def toDict(self)->dict: + return self.data + + @classmethod + @beartype + def fromDict(cls, inputDict:dict)->Any: + return cls(data=inputDict) + + @beartype + def update(self,inputDict:dict)->None: + self.data.update(inputDict) +``` + +``` +from nicHelper.exception import errorString +try: + test = TestModel.fromDict({'iprcode': 4, 'cprcode': 123 , 'oprCode': '123', 'orderId': 123}) + test.save() +except Exception as e: + print(e) + print(errorString()) + + +next(TestModel.query('1')) +``` + + + + + {"data": {"type": "pick up", "street_address": "123", "id": "123", "city": "sth", "state": "CA", "zip": "23523", "capacity": 5, "status": "open"}} + + + +### createData +create a new row of data + +``` +## lambda create function +def create (event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + r = createData(event2, hashKeyName='phoneHash', mainClass=TestModel) + if r.get('statusCode') != 200: return r + r2 = next(TestModel.query(body['phoneHash']), None) + if not r2: return Response.returnError('st wrong with saving, saving but didnt go through') + return Response.returnSuccess(r2) +``` + +``` +schemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json' +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +item = next(TestModel.queryId('123'), None) +print('existing item is :',item) +# delete item if exist +if item: + print(item.delete()) +create(event) +``` + + existing item is : {"creationTime": 1615893836.030621, "data": {"phoneHash": "123", "iprcode": 5, "cprcode": 123, "oprCode": "1234", "id": "123"}, "lastEdited": 1615894057.181481, "phoneHash": "123"} + {'ConsumedCapacity': {'CapacityUnits': 1.0, 'TableName': 'colab-test-sensitive-column'}} + + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### getData + +``` +def lambdaGet(event, *args): + query = Event.parseBody(event) + if 'key' not in query: return Response.returnError(f'missing key') + return getData(query['key'], TestModel) +``` + +``` +data = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'} +event = Event.getInput(data) +create(event) + +lambdaGet(Event.getInput({'key': '123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":4,"cprcode":123,"oprCode":"123","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +### updateData + +``` +def update(event, *args): + body = Event.parseBody(event) + body['id'] = body['phoneHash'] + + event2 = Event.getInput(body) + hashKeyname = 'id' + return updateData(event2, hashKeyName=hashKeyname, mainClass=TestModel) +``` + +``` +r = create(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '123'})) +r = update(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '1234'})) +lambdaGet(Event.getInput({'key':'123'})) +``` + + + + + {'body': '{"phoneHash":"123","iprcode":5,"cprcode":123,"oprCode":"1234","id":"123"}', + 'statusCode': 200, + 'headers': {'Access-Control-Allow-Headers': '*', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': '*'}} + + + +## Timer + +``` +from nicHelper.timer import Timer +``` + +### setting start timer + +``` +timer = Timer() +timer.t0 +``` + + + + + datetime.datetime(2021, 4, 16, 6, 57, 1, 236974) + + + +### print the time between starting time and current time + +``` +timer.print_time() +``` + + fuction took :3.422775 s + + + + + + 3.422775 + + + +### print the time between starting time and current time and reset the timer + +``` +timer.print_reset() +``` + + function took :0.376299 s + + + + + + 0.376299 + + + + +%prep +%autosetup -n nicHelper-0.0.110 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-nicHelper -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 0.0.110-1 +- Package Spec generated |
