# 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
Raw data
{
"_id": null,
"home_page": "https://github.com/thanakijwanavit/nicHelper/tree/master/",
"name": "nicHelper",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "nicHelper",
"author": "nic wanavit",
"author_email": "nwanavit@hatari.cc",
"download_url": "https://files.pythonhosted.org/packages/b2/ca/bd66a58d2c8df751f2c7c81bc647cc4af105fa817125f97fd101b15415d1/nichelper-0.0.119.tar.gz",
"platform": null,
"description": "# Helpers\n> various helpers from nic gist\n\n\nfull docs here\nhttps://thanakijwanavit.github.io/nicHelper/\n\n```\nfrom nicHelper.wrappers import add_method\n```\n\n## Install\n\n`pip install nicHelper`\n\n# How to use\n\n## method module\n\n### add method to a class\n\n```\nclass A:\n pass\n\n@add_method(A)\ndef printHello(self):\n print('hello')\n \nA().printHello()\n```\n\n hello\n\n\nThis is equivalent to \n```\nclass A:\n def printHello(self):\n print('hello')\n \n```\n\n## Dict utilities\n\n### Pretty print a dict\nprint only the first 10 characters of dict key, works with deep nested dict\n\n```\nfrom nicHelper.dictUtil import printDict\nprintDict({'key':'sjfhdkljhafsdlkjhdfaslkjhkljfadshklhfa', 'nestedKey':{'nestedKey2':'938023840843', 'nested3':{'nested4':'hello'}}})\n```\n\n key : sjfhdkljha\n nestedKey\n nestedKey2 : 9380238408\n nested3\n nested4 : hello\n\n\n### change all nested datetime object into timestamp for json compatibility\n\n```\nfrom nicHelper.dictUtil import filterDt\nfrom datetime import datetime\n\nfilterDt({'time': {'time2':datetime.now()}, 'hello': 'world'})\n```\n\n\n\n\n {'time': {'time2': 1615312774.297602}, 'hello': 'world'}\n\n\n\n## Exception module\n\n```\nfrom nicHelper.exception import errorString\ntry:\n error\nexcept:\n print(f'error is \\n{errorString()}')\n```\n\n error is \n Traceback (most recent call last):\n File \"<ipython-input-6-86083feec525>\", line 3, in <module>\n error\n NameError: name 'error' is not defined\n \n\n\n## Image utils\n\n```\nfrom nicHelper.images import imageFromUrl, imageToS3, showImgS3, resizeImage\nfrom s3bz.s3bz import S3\n```\n\n```\n## test variables\nkey = 'testCat.png'\npath = '/tmp/testCat.png'\nbucket = 'villa-remove-bg-small-output'\nurl = 'https://sites.google.com/site/funnycatmeawww/_/rsrc/1422326075261/home/6997052-funny-cat.jpg?height=675&width=1200'\n```\n\n### Resize images\n\n```\nresizeImage(url, 400)\n```\n\n\n\n\n \n\n \n\n\n\n### load image from url\n\n```\nimg = imageFromUrl(url)\ntype(img)\n```\n\n\n\n\n PIL.JpegImagePlugin.JpegImageFile\n\n\n\n### save Image to S3\n\n```\nimageToS3(img, bucket, key)\nS3.exist(key,bucket)\n```\n\n saving image to villa-remove-bg-small-output/testCat.png\n\n\n\n\n\n True\n\n\n\n### display image from s3\n\n```\n## full test\nshowImgS3(bucket, key)\n```\n\n\n \n\n \n\n\n## Secrets\n\n```\nfrom nicHelper.secrets import getSecret\nsecret = getSecret(name=\"removeBg\", region='ap-southeast-1')\n```\n\n## Shorten link with tenxor.sh\n\n```\nfrom nicHelper.shortenLink import shorten\n```\n\n```\nshorten('https://www.youtube.com/watch?v=fp85zRg2cwg')\n```\n\n\n\n\n 'https://tenxor.sh/d3Cp'\n\n\n\n## Schema\n\n```\nfrom nicHelper.schema import getSchemaPath, validateUrl, typeMapJsonSchema\n```\n\n### Get schema from path \n\n```\ntestSchema = 'https://gist.githubusercontent.com/thanakijwanavit/e2720d091ae0cef710a49b57c0c9cd4c/raw/ed2d322eac4900ee0f95b431d0f9067a40f3e0f0/squirrelOpenApiV0.0.3.yaml'\npath = 'components/schemas/Location'\ngetSchemaPath(testSchema, path)\n```\n\n\n\n\n {'type': 'object',\n 'required': ['id',\n 'type',\n 'street_address',\n 'city',\n 'state',\n 'zip',\n 'capacity',\n 'status'],\n 'properties': {'id': {'type': 'string', 'format': 'uuid'},\n 'type': {'type': 'string', 'enum': ['pick up', 'drop off', 'overnight']},\n 'street_address': {'type': 'string'},\n 'city': {'type': 'string'},\n 'state': {'type': 'string',\n '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]))$'},\n 'zip': {'type': 'string', 'pattern': '(^\\\\d{5}$)|(^\\\\d{5}-\\\\d{4}$)'},\n 'status': {'type': 'string', 'enum': ['open', 'in use']},\n 'created': {'type': 'string', 'format': 'date-time'},\n 'modified': {'type': 'string', 'format': 'date-time'}}}\n\n\n\n### Validate Url\n\n```\nurl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json'\ninput_ = {'iprcode': 4, 'cprcode': 123 , 'oprCode': '123'}\nvalidateUrl(url, input_)\n```\n\n\n\n\n namespace(cprcode=123, iprcode=4, oprCode='123')\n\n\n\n### Convert type to comply with json schema \n\n```\nurl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/dev-manual/inventory/inventory.yaml'\ninv = {\n 'iprcode': '0000009',\n 'brcode': '1000',\n 'ib_cf_qty': '50',\n 'new_ib_vs_stock_cv': '27',\n 'onlineflag': True\n }\ntypeMapJsonSchema(url, input_=inv)\n```\n\n typesDict is: {'iprcode': <class 'int'>, 'brcode': <class 'int'>, 'ib_cf_qty': <class 'int'>, 'new_ib_vs_stock_cv': <class 'int'>, 'onlineflag': <class 'bool'>}\n\n\n\n\n\n {'iprcode': 9,\n 'brcode': 1000,\n 'ib_cf_qty': 50,\n 'new_ib_vs_stock_cv': 27,\n 'onlineflag': True}\n\n\n\n## Pynamodb\n\n```\nfrom nicHelper.pynamodb import SchemaAttribute, SuperModel, createData, getData, updateData\nfrom pynamodb.attributes import Attribute, UnicodeAttribute, NumberAttribute\nfrom beartype import beartype\nfrom awsSchema.apigateway import Event, Response\n```\n\n### SchemaAttribute\na class which automatically parse and check data against json schema\n\n```SchemaAttribute(*args, **kwargs) :: Attribute```\n\n### Supermodel\na class which add some functionalities on top of the standard pynamodb model\n\n```\nschemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json'\nfrom typing import Any\nclass TestModel(SuperModel):\n class Meta:\n table_name=\"colab-test-sensitive-column\"\n region = 'ap-southeast-1'\n data = SchemaAttribute(schemaUrl = schemaUrl, null=True)\n phoneHash = UnicodeAttribute(hash_key=True)\n \n \n # Overrides\n def pullOutKeys(self)->None:\n self.phoneHash = str(self.data.get('phoneHash') or self.data.get('iprcode') or self.data.get('id') )\n\n @beartype\n def toDict(self)->dict:\n return self.data\n \n @classmethod\n @beartype\n def fromDict(cls, inputDict:dict)->Any:\n return cls(data=inputDict)\n \n @beartype \n def update(self,inputDict:dict)->None:\n self.data.update(inputDict)\n```\n\n```\nfrom nicHelper.exception import errorString\ntry:\n test = TestModel.fromDict({'iprcode': 4, 'cprcode': 123 , 'oprCode': '123', 'orderId': 123})\n test.save()\nexcept Exception as e:\n print(e)\n print(errorString())\n\n\nnext(TestModel.query('1'))\n```\n\n\n\n\n {\"data\": {\"type\": \"pick up\", \"street_address\": \"123\", \"id\": \"123\", \"city\": \"sth\", \"state\": \"CA\", \"zip\": \"23523\", \"capacity\": 5, \"status\": \"open\"}}\n\n\n\n### createData\ncreate a new row of data\n\n```\n## lambda create function\ndef create (event, *args):\n body = Event.parseBody(event)\n body['id'] = body['phoneHash']\n \n event2 = Event.getInput(body)\n r = createData(event2, hashKeyName='phoneHash', mainClass=TestModel)\n if r.get('statusCode') != 200: return r\n r2 = next(TestModel.query(body['phoneHash']), None)\n if not r2: return Response.returnError('st wrong with saving, saving but didnt go through')\n return Response.returnSuccess(r2)\n```\n\n```\nschemaUrl = 'https://raw.githubusercontent.com/thanakijwanavit/villaMasterSchema/master/Product.json'\ndata = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'}\nevent = Event.getInput(data)\nitem = next(TestModel.queryId('123'), None)\nprint('existing item is :',item)\n# delete item if exist\nif item:\n print(item.delete())\ncreate(event)\n```\n\n existing item is : {\"creationTime\": 1615893836.030621, \"data\": {\"phoneHash\": \"123\", \"iprcode\": 5, \"cprcode\": 123, \"oprCode\": \"1234\", \"id\": \"123\"}, \"lastEdited\": 1615894057.181481, \"phoneHash\": \"123\"}\n {'ConsumedCapacity': {'CapacityUnits': 1.0, 'TableName': 'colab-test-sensitive-column'}}\n\n\n\n\n\n {'body': '{\"phoneHash\":\"123\",\"iprcode\":4,\"cprcode\":123,\"oprCode\":\"123\",\"id\":\"123\"}',\n 'statusCode': 200,\n 'headers': {'Access-Control-Allow-Headers': '*',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': '*'}}\n\n\n\n### getData\n\n```\ndef lambdaGet(event, *args):\n query = Event.parseBody(event)\n if 'key' not in query: return Response.returnError(f'missing key')\n return getData(query['key'], TestModel)\n```\n\n```\ndata = {'phoneHash': '123','iprcode': 4, 'cprcode': 123 , 'oprCode': '123'}\nevent = Event.getInput(data)\ncreate(event)\n\nlambdaGet(Event.getInput({'key': '123'}))\n```\n\n\n\n\n {'body': '{\"phoneHash\":\"123\",\"iprcode\":4,\"cprcode\":123,\"oprCode\":\"123\",\"id\":\"123\"}',\n 'statusCode': 200,\n 'headers': {'Access-Control-Allow-Headers': '*',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': '*'}}\n\n\n\n### updateData\n\n```\ndef update(event, *args):\n body = Event.parseBody(event)\n body['id'] = body['phoneHash']\n \n event2 = Event.getInput(body)\n hashKeyname = 'id'\n return updateData(event2, hashKeyName=hashKeyname, mainClass=TestModel)\n```\n\n```\nr = create(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '123'}))\nr = update(Event.getInput({'phoneHash': '123','iprcode': 5, 'cprcode': 123 , 'oprCode': '1234'}))\nlambdaGet(Event.getInput({'key':'123'}))\n```\n\n\n\n\n {'body': '{\"phoneHash\":\"123\",\"iprcode\":5,\"cprcode\":123,\"oprCode\":\"1234\",\"id\":\"123\"}',\n 'statusCode': 200,\n 'headers': {'Access-Control-Allow-Headers': '*',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': '*'}}\n\n\n\n## Timer\n\n```\nfrom nicHelper.timer import Timer\n```\n\n### setting start timer\n\n```\ntimer = Timer()\ntimer.t0\n```\n\n\n\n\n datetime.datetime(2021, 4, 16, 6, 57, 1, 236974)\n\n\n\n### print the time between starting time and current time\n\n```\ntimer.print_time()\n```\n\n fuction took :3.422775 s\n\n\n\n\n\n 3.422775\n\n\n\n### print the time between starting time and current time and reset the timer\n\n```\ntimer.print_reset()\n```\n\n function took :0.376299 s\n\n\n\n\n\n 0.376299\n\n\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "some helper functions from nic's gist",
"version": "0.0.119",
"project_urls": {
"Homepage": "https://github.com/thanakijwanavit/nicHelper/tree/master/"
},
"split_keywords": [
"nichelper"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c4f38c927512e6ccc2a9ed9207cf606ecd63152e7667d6b063c1827b0081faa6",
"md5": "32f8de67031258353b5ba91dbecf1800",
"sha256": "ba12536e95d1386c11658c3829c17589c1cccb17d85f00546ce20fdaef59a035"
},
"downloads": -1,
"filename": "nicHelper-0.0.119-py3-none-any.whl",
"has_sig": false,
"md5_digest": "32f8de67031258353b5ba91dbecf1800",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 37268,
"upload_time": "2024-09-15T11:51:07",
"upload_time_iso_8601": "2024-09-15T11:51:07.595173Z",
"url": "https://files.pythonhosted.org/packages/c4/f3/8c927512e6ccc2a9ed9207cf606ecd63152e7667d6b063c1827b0081faa6/nicHelper-0.0.119-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b2cabd66a58d2c8df751f2c7c81bc647cc4af105fa817125f97fd101b15415d1",
"md5": "b2251ec3ce028837799573fd8d4ed1f4",
"sha256": "085bbc80b6e9c313f304b2a61bdc5746e11bc3ec389ab5248db7b1ecbd4f2ced"
},
"downloads": -1,
"filename": "nichelper-0.0.119.tar.gz",
"has_sig": false,
"md5_digest": "b2251ec3ce028837799573fd8d4ed1f4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 31360,
"upload_time": "2024-09-15T11:51:09",
"upload_time_iso_8601": "2024-09-15T11:51:09.762945Z",
"url": "https://files.pythonhosted.org/packages/b2/ca/bd66a58d2c8df751f2c7c81bc647cc4af105fa817125f97fd101b15415d1/nichelper-0.0.119.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-15 11:51:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "thanakijwanavit",
"github_project": "nicHelper",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "nichelper"
}