# Wrenchbox for Python
A set of utilities for daily development.
本项目是一些常用的 Python 工具集合。
## Install
```shell
pip install -U wrenchbox
```
## Usage
### Alert Hanlder
Send alerts to certain bots or web APIs.
通过钉钉机器人等渠道发送报警信息。
```shell
$ python3 -u -m wrenchbox.alert -h
usage: alert.py [-h] [--debug] --type TYPE [--token TOKEN] msg
positional arguments:
msg the message
optional arguments:
-h, --help show this help message and exit
--debug show debug information
--type TYPE, -p TYPE alert type, must be "dingtalk"
--token TOKEN, -k TOKEN
access token, if any
```
```python
from wrenchbox.alert import DingTalk
DingTalk('token').send('This is a warning message.')
```
```json
200
```
### Configuration Parser
Read a configuration from a YAML or JSON file.
从 YAML 或 JSON 中读取一段配置信息。
```shell
$ python3 -u -m wrenchbox.config -h
usage: config.py [-h] [--debug] config
positional arguments:
config config file
optional arguments:
-h, --help show this help message and exit
--debug show debug information
```
```python
from wrenchbox.config import Configuration
print(json.dumps(Configuration('wrenchbox/config.yml').__dict__, indent=2))
```
```json
{
"version": 0,
"name": "00000000-0000-0000-0000-000000000000",
"config": {
"key": "value",
"nested": {
"key": "value"
},
"list": [
{
"key": "value"
},
{
"key": "value"
}
]
}
}
```
The following configurations will be automatically generated if not provided:
- `version` version of the configuration file, could be verified through `Configuration(version=(0,))`
- `worker` ID of the worker, default: 0
- `name` name of the worker, an [UUID](https://www.uuidgenerator.net/) will be generated if not provided
All configuration keys starting with `-` or `.` will be ignored (these keys should be used as audition only).
### Database Hanlder
An advanced database handler based on [SQLAlchemy](https://www.sqlalchemy.org/).
一个基于 [SQLAlchemy](https://www.sqlalchemy.org/) 开发的更简单的数据库处理模块。
```python
from wrenchbox.database import DatabaseHandler
DatabaseHandler({
'test': 'sqlite:///test.db'
}, [
('test', 'test')
]).handle(
'test', {
'id': 1
}, {
'id': 1,
'name': str(datetime.now())
}, replace=True
)
```
The above code will insert or update a record with `id` = `1`.
### Datetime Hanlder
An advanced datetime handler based on [python-dateutil](https://pypi.org/project/python-dateutil/).
一个基于 [python-dateutil](https://pypi.org/project/python-dateutil/) 开发的更简单的日期和时间处理器。
```python
from wrenchbox.datetime import T
print(T().timestamp()) # Get timestamp
print(T().format()) # Format into YYYY-MM-DD HH:MM:SS
print(T().format('d')) # Format into YYYY-MM-DD
print(T().format('t')) # Format into HH:MM:SS
```
```
1598930603.003622
2020-09-01 11:23:23
2020-09-01
11:23:23
```
When initialising `T`, it is possible to pass the following arguments:
- `None` current timestamp will be generated
- `datetime.datetime` will be directly used
- `float` or `int` will be parsed as timestamp
- `str` will be parsed through [python-dateutil](https://pypi.org/project/python-dateutil/)
### Dictionary Hanlder
An advanced dictionary hander providing various tools.
提供了多种多样的字典(dict)处理工具。
```python
from wrenchbox.dict import EnhancedDict
dict_a = {
'a': 'a',
'b': {
'a': 1,
'b': {
'a': 1,
'b': [{
'a': 1,
'b': 2
}, {
'a': 1,
'b': {
'a': 1,
'b': 2
}
}]
}
}
}
dict_b = {
'a': 1,
'b': {
'b': {
'b': 2
}
}
}
print(dict_a)
print(dict_b)
print(EnhancedDict(dict_a).search('a'))
print(EnhancedDict(dict_a).merge(dict_b))
print(EnhancedDict(dict_b).flatten())
print(EnhancedDict(dict_a).format(lambda x: x + 10, lambda x: isinstance(x, int)))
print(EnhancedDict(dict_a).remove_key('a'))
print(EnhancedDict(dict_a).remove_value(1))
```
```json
{"a": "a", "b": {"a": 1, "b": {"a": 1, "b": [{"a": 1, "b": 2}, {"a": 1, "b": {"a": 1, "b": 2}}]}}}
{"a": 1, "b": {"b": {"b": 2}}}
["a", 1, 1, 1, 1, 1]
{"a": 1, "b": {"a": 1, "b": {"a": 1, "b": 2}}}
{"a": 1, "b_b_b": 2}
{"a": "a", "b": {"a": 11, "b": {"a": 11, "b": [{"a": 11, "b": 12}, {"a": 11, "b": {"a": 11, "b": 12}}]}}}
{"b": {"b": {"b": [{"b": 2}, {"b": {"b": 2}}]}}}
{"a": "a", "b": {"b": {"b": [{"b": 2}, {"b": {"b": 2}}]}}}
```
### IO Handler
An advanced IO handerl providing various tools.
提供了多种多样的 IO 工具。
```python
from wrenchbox.io import BufferedWriter
w = BufferedWriter(buffer=50)
for i in range(100):
w.write(i)
w.close()
```
The above code will write two separate files with 50 records each.
### List Hanlder
An advanced list hander providing various tools.
提供了多种多样的列表(list)处理工具。
```python
from wrenchbox.list import EnhancedList
list_a = [1, [1, [2, 3], 2], 2]
print(list_a)
print(EnhancedList(list_a).flatten()) # Flatten the list and put all sub-lists into the root level
print(EnhancedList(list_a).pick(lambda x: x == 1)) # Pick values based on a function
print(EnhancedList(list_a).format(lambda x: x + 1, lambda x: isinstance(x, (int, float)))) # Format values of the list through a filter
```
```json
[1, [1, [2, 3], 2], 2]
[1, 1, 2, 3, 2, 2]
[1, [1]]
[[[2, 3], 2], 2]
[2, [2, [3, 4], 3], 3]
```
### Logging Tools
A series of tools for logging.
提供了美化的日志工具。
```python
from wrenchbox.logging import setup_log, progress
# Create a colorized logger and print logging messages
setup_log(level=logging.DEBUG, path='./log/', tag='wrenchbox')
logging.debug('This is a DEBUG message.')
logging.info('This is an INFO message.')
logging.warning('This is a WARNING message.')
logging.error('This is an ERROR message.')
logging.critical('This is an CRITICAL message.')
# Show a progress bar
for _i in range(100):
progress(_i, 100)
time.sleep(0.02)
```
```
[2020-09-28 10:18:40,084] This is a DEBUG message.
[2020-09-28 10:18:40,084] This is an INFO message.
[2020-09-28 10:18:40,084] This is a WARNING message.
[2020-09-28 10:18:40,085] This is an ERROR message.
[2020-09-28 10:18:40,085] This is an CRITICAL message.
[==========================================================--] 97.0%
```
Logs are colorized with the following default config:
```json
{
DEBUG: "cyan",
INFO: "green",
WARNING: "yellow",
ERROR: "red",
CRITICAL: "magenta"
}
```
### Number Hanlder
An advanced number hander providing various tools.
提供了多种多样的数字(number)处理工具。
```python
from wrenchbox.number import EnhancedDecimal
print(EnhancedDecimal('3.1415926').round(Decimal('0.1'))) # Round a decimal with any unit like in excel
```
```json
3.1
```
### Object Tools
A series of objects for specific uses.
提供了一些杂项对象。
- `Dict2StrSafe`: a class that correctly converts `self.__dict__` to a JSON string without errors
- `Munch`: an alternative implementation of [Munch](https://github.com/Infinidat/munch)
### Snowflake Code Generator
Generate a series of [Twitter Snowflake Codes](https://developer.twitter.com/en/docs/basics/twitter-ids).
生成若干 [Twitter Snowflake Codes](https://developer.twitter.com/en/docs/basics/twitter-ids)。
```shell
$ python3 -u -m wrenchbox.snowflake -h
usage: snowflake.py [-h] [--debug] [--twepoch TWEPOCH] [-d D] -w W n
positional arguments:
n # of results
optional arguments:
-h, --help show this help message and exit
--debug show debug information
--twepoch TWEPOCH twitter epoch, default: 1483228800000
-d D data center id, default: 31
-w W worker id, 0-31
```
```python
from wrenchbox.snowflake import Snowflake
print(next(Snowflake(twepoch=1483228800000).generate(31)))
```
```json
495059711868006400
```
### String Handler
An advanced string hander providing various tools.
提供了多种多样的字符串(string)处理工具。
```python
from wrenchbox.string import digits, random_chars, random_letters, random_numbers
print(digits(pi)) # Count the digits of a given float number
print(random_chars(3)) # Generate a random string from [a-zA-Z0-9]
print(random_letters(3)) # Generate a random string from [a-zA-Z]
print(random_numbers(3)) # Generate a random string from [0-9]
```
```
15
63f
FVK
007
```
### Text Handler
A set of advanced text processing modules.
提供了多种多样的文本处理工具。
```shell
$ python3 -u -m wrenchbox.text -h
usage: text.py [-h] [--debug] [--chinese] [-p P] f
positional arguments:
f file path
optional arguments:
-h, --help show this help message and exit
--debug show debug information
--chinese specify the input as Chinese
-p P part of speech to show, only works for Chinese
```
```python
from wrenchbox.text import S
print([i for i in S(open('test.txt', 'r').read()).v(chinese=True).words if i[1] in ('v',)])
```
```json
[("是", "v", 8), ("获取", "v", 1)]
```
Raw data
{
"_id": null,
"home_page": "https://github.com/valency/wrenchbox",
"name": "wrenchbox",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "toolbox,tools",
"author": "Ye Ding",
"author_email": "guiewy@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/c5/a3/f35c4e87115551be1cb6a77273dbb20318c14a6b537e150692d9713bbb2f/wrenchbox-1.12.27.tar.gz",
"platform": null,
"description": "# Wrenchbox for Python\n\nA set of utilities for daily development.\n\n\u672c\u9879\u76ee\u662f\u4e00\u4e9b\u5e38\u7528\u7684 Python \u5de5\u5177\u96c6\u5408\u3002\n\n## Install\n\n```shell\npip install -U wrenchbox\n```\n\n## Usage\n\n### Alert Hanlder\n\nSend alerts to certain bots or web APIs.\n\n\u901a\u8fc7\u9489\u9489\u673a\u5668\u4eba\u7b49\u6e20\u9053\u53d1\u9001\u62a5\u8b66\u4fe1\u606f\u3002\n\n```shell\n$ python3 -u -m wrenchbox.alert -h\nusage: alert.py [-h] [--debug] --type TYPE [--token TOKEN] msg\n\npositional arguments:\n msg the message\n\noptional arguments:\n -h, --help show this help message and exit\n --debug show debug information\n --type TYPE, -p TYPE alert type, must be \"dingtalk\"\n --token TOKEN, -k TOKEN\n access token, if any\n```\n\n```python\nfrom wrenchbox.alert import DingTalk\nDingTalk('token').send('This is a warning message.')\n```\n\n```json\n200\n```\n\n### Configuration Parser\n\nRead a configuration from a YAML or JSON file.\n\n\u4ece YAML \u6216 JSON \u4e2d\u8bfb\u53d6\u4e00\u6bb5\u914d\u7f6e\u4fe1\u606f\u3002\n\n```shell\n$ python3 -u -m wrenchbox.config -h\nusage: config.py [-h] [--debug] config\n\npositional arguments:\n config config file\n\noptional arguments:\n -h, --help show this help message and exit\n --debug show debug information\n```\n\n```python\nfrom wrenchbox.config import Configuration\nprint(json.dumps(Configuration('wrenchbox/config.yml').__dict__, indent=2))\n```\n\n```json\n{\n \"version\": 0,\n \"name\": \"00000000-0000-0000-0000-000000000000\",\n \"config\": {\n \"key\": \"value\",\n \"nested\": {\n \"key\": \"value\"\n },\n \"list\": [\n {\n \"key\": \"value\"\n },\n {\n \"key\": \"value\"\n }\n ]\n }\n}\n```\n\nThe following configurations will be automatically generated if not provided:\n\n- `version` version of the configuration file, could be verified through `Configuration(version=(0,))`\n- `worker` ID of the worker, default: 0\n\n- `name` name of the worker, an [UUID](https://www.uuidgenerator.net/) will be generated if not provided\n\nAll configuration keys starting with `-` or `.` will be ignored (these keys should be used as audition only).\n\n### Database Hanlder\n\nAn advanced database handler based on [SQLAlchemy](https://www.sqlalchemy.org/).\n\n\u4e00\u4e2a\u57fa\u4e8e [SQLAlchemy](https://www.sqlalchemy.org/) \u5f00\u53d1\u7684\u66f4\u7b80\u5355\u7684\u6570\u636e\u5e93\u5904\u7406\u6a21\u5757\u3002\n\n```python\nfrom wrenchbox.database import DatabaseHandler\nDatabaseHandler({\n 'test': 'sqlite:///test.db'\n}, [\n ('test', 'test')\n]).handle(\n 'test', {\n 'id': 1\n }, {\n 'id': 1,\n 'name': str(datetime.now())\n }, replace=True\n)\n```\n\nThe above code will insert or update a record with `id` = `1`.\n\n### Datetime Hanlder\n\nAn advanced datetime handler based on [python-dateutil](https://pypi.org/project/python-dateutil/).\n\n\u4e00\u4e2a\u57fa\u4e8e [python-dateutil](https://pypi.org/project/python-dateutil/) \u5f00\u53d1\u7684\u66f4\u7b80\u5355\u7684\u65e5\u671f\u548c\u65f6\u95f4\u5904\u7406\u5668\u3002\n\n```python\nfrom wrenchbox.datetime import T\nprint(T().timestamp()) # Get timestamp\nprint(T().format()) # Format into YYYY-MM-DD HH:MM:SS\nprint(T().format('d')) # Format into YYYY-MM-DD\nprint(T().format('t')) # Format into HH:MM:SS\n```\n\n```\n1598930603.003622\n2020-09-01 11:23:23\n2020-09-01\n11:23:23\n```\n\nWhen initialising `T`, it is possible to pass the following arguments:\n\n- `None` current timestamp will be generated\n- `datetime.datetime` will be directly used\n- `float` or `int` will be parsed as timestamp\n- `str` will be parsed through [python-dateutil](https://pypi.org/project/python-dateutil/)\n\n### Dictionary Hanlder\n\nAn advanced dictionary hander providing various tools.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684\u5b57\u5178\uff08dict\uff09\u5904\u7406\u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.dict import EnhancedDict\ndict_a = {\n 'a': 'a',\n 'b': {\n 'a': 1,\n 'b': {\n 'a': 1,\n 'b': [{\n 'a': 1,\n 'b': 2\n }, {\n 'a': 1,\n 'b': {\n 'a': 1,\n 'b': 2\n }\n }]\n }\n }\n}\ndict_b = {\n 'a': 1,\n 'b': {\n 'b': {\n 'b': 2\n }\n }\n}\nprint(dict_a)\nprint(dict_b)\nprint(EnhancedDict(dict_a).search('a'))\nprint(EnhancedDict(dict_a).merge(dict_b))\nprint(EnhancedDict(dict_b).flatten())\nprint(EnhancedDict(dict_a).format(lambda x: x + 10, lambda x: isinstance(x, int)))\nprint(EnhancedDict(dict_a).remove_key('a'))\nprint(EnhancedDict(dict_a).remove_value(1))\n```\n\n```json\n{\"a\": \"a\", \"b\": {\"a\": 1, \"b\": {\"a\": 1, \"b\": [{\"a\": 1, \"b\": 2}, {\"a\": 1, \"b\": {\"a\": 1, \"b\": 2}}]}}}\n{\"a\": 1, \"b\": {\"b\": {\"b\": 2}}}\n[\"a\", 1, 1, 1, 1, 1]\n{\"a\": 1, \"b\": {\"a\": 1, \"b\": {\"a\": 1, \"b\": 2}}}\n{\"a\": 1, \"b_b_b\": 2}\n{\"a\": \"a\", \"b\": {\"a\": 11, \"b\": {\"a\": 11, \"b\": [{\"a\": 11, \"b\": 12}, {\"a\": 11, \"b\": {\"a\": 11, \"b\": 12}}]}}}\n{\"b\": {\"b\": {\"b\": [{\"b\": 2}, {\"b\": {\"b\": 2}}]}}}\n{\"a\": \"a\", \"b\": {\"b\": {\"b\": [{\"b\": 2}, {\"b\": {\"b\": 2}}]}}}\n```\n\n### IO Handler\n\nAn advanced IO handerl providing various tools.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684 IO \u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.io import BufferedWriter\nw = BufferedWriter(buffer=50)\nfor i in range(100):\n w.write(i) \nw.close()\n```\n\nThe above code will write two separate files with 50 records each.\n\n### List Hanlder\n\nAn advanced list hander providing various tools.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684\u5217\u8868\uff08list\uff09\u5904\u7406\u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.list import EnhancedList\nlist_a = [1, [1, [2, 3], 2], 2]\nprint(list_a)\nprint(EnhancedList(list_a).flatten()) # Flatten the list and put all sub-lists into the root level\nprint(EnhancedList(list_a).pick(lambda x: x == 1)) # Pick values based on a function\nprint(EnhancedList(list_a).format(lambda x: x + 1, lambda x: isinstance(x, (int, float)))) # Format values of the list through a filter\n```\n\n```json\n[1, [1, [2, 3], 2], 2]\n[1, 1, 2, 3, 2, 2]\n[1, [1]]\n[[[2, 3], 2], 2]\n[2, [2, [3, 4], 3], 3]\n```\n\n### Logging Tools\n\nA series of tools for logging.\n\n\u63d0\u4f9b\u4e86\u7f8e\u5316\u7684\u65e5\u5fd7\u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.logging import setup_log, progress\n# Create a colorized logger and print logging messages\nsetup_log(level=logging.DEBUG, path='./log/', tag='wrenchbox')\nlogging.debug('This is a DEBUG message.')\nlogging.info('This is an INFO message.')\nlogging.warning('This is a WARNING message.')\nlogging.error('This is an ERROR message.')\nlogging.critical('This is an CRITICAL message.')\n# Show a progress bar\nfor _i in range(100):\n progress(_i, 100)\n time.sleep(0.02)\n```\n\n```\n[2020-09-28 10:18:40,084] This is a DEBUG message.\n[2020-09-28 10:18:40,084] This is an INFO message.\n[2020-09-28 10:18:40,084] This is a WARNING message.\n[2020-09-28 10:18:40,085] This is an ERROR message.\n[2020-09-28 10:18:40,085] This is an CRITICAL message.\n[==========================================================--] 97.0%\n```\n\nLogs are colorized with the following default config:\n\n```json\n{\n DEBUG: \"cyan\",\n INFO: \"green\",\n WARNING: \"yellow\",\n ERROR: \"red\",\n CRITICAL: \"magenta\"\n}\n```\n\n### Number Hanlder\n\nAn advanced number hander providing various tools.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684\u6570\u5b57\uff08number\uff09\u5904\u7406\u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.number import EnhancedDecimal\nprint(EnhancedDecimal('3.1415926').round(Decimal('0.1'))) # Round a decimal with any unit like in excel\n```\n\n```json\n3.1\n```\n\n### Object Tools\n\nA series of objects for specific uses.\n\n\u63d0\u4f9b\u4e86\u4e00\u4e9b\u6742\u9879\u5bf9\u8c61\u3002\n\n- `Dict2StrSafe`: a class that correctly converts `self.__dict__` to a JSON string without errors\n- `Munch`: an alternative implementation of [Munch](https://github.com/Infinidat/munch)\n\n### Snowflake Code Generator\n\nGenerate a series of [Twitter Snowflake Codes](https://developer.twitter.com/en/docs/basics/twitter-ids).\n\n\u751f\u6210\u82e5\u5e72 [Twitter Snowflake Codes](https://developer.twitter.com/en/docs/basics/twitter-ids)\u3002\n\n```shell\n$ python3 -u -m wrenchbox.snowflake -h\nusage: snowflake.py [-h] [--debug] [--twepoch TWEPOCH] [-d D] -w W n\n\npositional arguments:\n n # of results\n\noptional arguments:\n -h, --help show this help message and exit\n --debug show debug information\n --twepoch TWEPOCH twitter epoch, default: 1483228800000\n -d D data center id, default: 31\n -w W worker id, 0-31\n```\n```python\nfrom wrenchbox.snowflake import Snowflake\nprint(next(Snowflake(twepoch=1483228800000).generate(31)))\n```\n\n```json\n495059711868006400\n```\n\n### String Handler\n\nAn advanced string hander providing various tools.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684\u5b57\u7b26\u4e32\uff08string\uff09\u5904\u7406\u5de5\u5177\u3002\n\n```python\nfrom wrenchbox.string import digits, random_chars, random_letters, random_numbers\nprint(digits(pi)) # Count the digits of a given float number\nprint(random_chars(3)) # Generate a random string from [a-zA-Z0-9]\nprint(random_letters(3)) # Generate a random string from [a-zA-Z]\nprint(random_numbers(3)) # Generate a random string from [0-9]\n```\n\n```\n15\n63f\nFVK\n007\n```\n\n### Text Handler\n\nA set of advanced text processing modules.\n\n\u63d0\u4f9b\u4e86\u591a\u79cd\u591a\u6837\u7684\u6587\u672c\u5904\u7406\u5de5\u5177\u3002\n\n```shell\n$ python3 -u -m wrenchbox.text -h\nusage: text.py [-h] [--debug] [--chinese] [-p P] f\n\npositional arguments:\n f file path\n\noptional arguments:\n -h, --help show this help message and exit\n --debug show debug information\n --chinese specify the input as Chinese\n -p P part of speech to show, only works for Chinese\n```\n\n```python\nfrom wrenchbox.text import S\nprint([i for i in S(open('test.txt', 'r').read()).v(chinese=True).words if i[1] in ('v',)])\n```\n\n```json\n[(\"\u662f\", \"v\", 8), (\"\u83b7\u53d6\", \"v\", 1)]\n```\n\n\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Wrenchbox",
"version": "1.12.27",
"split_keywords": [
"toolbox",
"tools"
],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "b4988505a63b98e023624abaa171fd5b",
"sha256": "56bbe2938073cca726aef04aa648ba08e888f4f07536818bfd9e867c26c98186"
},
"downloads": -1,
"filename": "wrenchbox-1.12.27.tar.gz",
"has_sig": false,
"md5_digest": "b4988505a63b98e023624abaa171fd5b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 29321,
"upload_time": "2022-12-27T08:46:38",
"upload_time_iso_8601": "2022-12-27T08:46:38.387252Z",
"url": "https://files.pythonhosted.org/packages/c5/a3/f35c4e87115551be1cb6a77273dbb20318c14a6b537e150692d9713bbb2f/wrenchbox-1.12.27.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-27 08:46:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "valency",
"github_project": "wrenchbox",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "wrenchbox"
}