Name | wipac-dev-tools JSON |
Version |
1.13.0
JSON |
| download |
home_page | None |
Summary | Common, basic, and reusable development tools |
upload_time | 2024-10-09 18:22:10 |
maintainer | None |
docs_url | None |
author | None |
requires_python | <3.14,>=3.9 |
license | MIT License Copyright (c) 2021 Wisconsin IceCube Particle Astrophysics Center Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
wipac
python
tools
utilities
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
<!--- Top of README Badges (automated) --->
[![PyPI](https://img.shields.io/pypi/v/wipac-dev-tools)](https://pypi.org/project/wipac-dev-tools/) [![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/WIPACrepo/wipac-dev-tools?include_prereleases)](https://github.com/WIPACrepo/wipac-dev-tools/) [![Versions](https://img.shields.io/pypi/pyversions/wipac-dev-tools.svg)](https://pypi.org/project/wipac-dev-tools) [![PyPI - License](https://img.shields.io/pypi/l/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/blob/main/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/WIPACrepo/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aopen) [![GitHub pull requests](https://img.shields.io/github/issues-pr/WIPACrepo/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Aopen)
<!--- End of README Badges (automated) --->
# wipac-dev-tools
Common, basic, and reusable development tools
## Utilities
### Logging Tools
#### `wipac_dev_tools.logging_tools.set_level()`
_Available for Python 3.6+_
```
def set_level(
level: LoggerLevel,
first_party_loggers: Union[
None, LogggerObjectOrName, List[LogggerObjectOrName]
] = None,
third_party_level: LoggerLevel = "WARNING",
future_third_parties: Union[None, str, List[str]] = None,
specialty_loggers: Optional[Dict[LogggerObjectOrName, LoggerLevel]] = None,
use_coloredlogs: bool = False,
) -> None:
"""Set the level of loggers of various precedence.
The root logger and first-party logger(s) are set to the same level (`level`).
Args:
`level`
the desired logging level (first-party), case-insensitive
`first_party_loggers`
a list (or a single instance) of `logging.Logger` or the loggers' names
`third_party_level`
the desired logging level for any other (currently) available loggers, case-insensitive
`future_third_parties`
additional third party logger(s) which have not yet been created (at call time)
`specialty_loggers`
additional loggers, each paired with a logging level, which are not
considered first-party nor third-party loggers. **These have the highest precedence**
`use_coloredlogs`
if True, will import and use the `coloredlogs` package.
This will set the logger format and use colored text.
"""
```
#### `wipac_dev_tools.logging_tools.log_argparse_args()`
_Available for Python 3.6+_
```
def log_argparse_args(
args: argparse.Namespace,
logger: Union[None, str, logging.Logger] = None,
level: LoggerLevel = "WARNING",
) -> argparse.Namespace:
"""Log the argparse args and their values at the given level.
Return the args (Namespace) unchanged.
Example:
2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING in_file: in_msg.pkl
2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING out_file: out_msg.pkl
2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING log: DEBUG
2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING log_third_party: WARNING
"""
```
### Environment Variable Tool(s)
#### `wipac_dev_tools.from_environment()`
_Available for Python 3.6+_
```
def from_environment(keys: KeySpec) -> Dict[str, RetVal]:
"""Obtain configuration values from the OS environment.
Parsing Details:
Types are inferred from the default values, and casted as such:
`bool`: *(case-insensitive)*:
- `True` => ("y", "yes", "t", "true", "on", or "1")
- `False` => ("n", "no", "f", "false", "off", or "0")
- `Error` => any other string
`int`: normal cast (`int(str)`)
`float`: normal cast (`float(str)`)
`other`: no change (`str`)
Arguments:
keys - Specify the configuration values to obtain.
This can be a string, specifying a single key, such as:
config_dict = from_environment("LANGUAGE")
This can be a list of strings, specifying multiple keys,
such as:
config_dict = from_environment(["HOME", "LANGUAGE"])
This can be a dictionary that provides some default values,
and will accept overrides from the environment:
default_config = {
"HOST": "localhost",
"PORT": 8080,
"REQUIRED_FROM_ENVIRONMENT": None
}
config_dict = from_environment(default_config)
Note in this case that if 'HOST' or 'PORT' were defined in the
environment, those values would be returned in config_dict. If
the values were not defined in the environment, the default values
from default_config would be returned in config_dict.
Also note, that if 'REQUIRED_FROM_ENVIRONMENT' is not defined,
an OSError will be raised. The sentinel value of None indicates
that the configuration parameter MUST be sourced from the
environment.
Returns:
a dictionary mapping configuration keys to configuration values
Raises:
OSError - If a configuration value is requested and no default
value is provided (via a dict), to indicate that the
component's configuration is incomplete due to missing
data from the OS.
ValueError - If a type-indicated value is not a legal value
"""
```
#### `wipac_dev_tools.from_environment_as_dataclass()`
_Available for Python >=3.9_
```
def from_environment_as_dataclass(
dclass: Type[T],
collection_sep: Optional[str] = None,
dict_kv_joiner: str = "=",
log_vars: Optional[logging_tools.LoggerLevel] = "WARNING",
) -> T:
"""Obtain configuration values from the OS environment formatted in a
dataclass.
Environment variables are matched to a dataclass field's name. The
matching environment string is cast using the dataclass field's type
(there are some special cases for built-in types, see below). Then,
the values are used to create a dataclass instance. All normal
dataclass init-behavior is expected, like required fields
(positional arguments), optional fields with defaults, default
factories, post-init processing, etc.
If a field's type is a bool, `wipac_dev_tools.strtobool` is applied.
If a field's type is a `list`, `dict`, `set`, `frozenset`, or
an analogous type alias from the 'typing' module, then a conversion
is made (see `collection_sep` and `dict_kv_joiner`). Sub-types
are cast if using a typing-module type alias. The typing-module's
alias types must resolve to `type` within 1 nesting (eg: List[bool]
and Dict[int, float] are okay; List[Dict[int, float]] is not), or
2 if using 'Final' or 'Optional' (ex: Final[Dict[int, float]]).
If a field's type is a class that accepts 1 argument, it is
instantiated as such.
Arguments:
dclass - a (non-instantiated) dataclass, aka a type
collection_sep - the delimiter to split collections on ("1 2 5")
dict_kv_joiner - the delimiter that joins key-value pairs ("a=1 b=2 c=1")
log_vars - what level to log the collected environment variables (set to `None` to not log)
Returns:
a dataclass instance mapping configuration keys to configuration values
Example:
env:
FPATH=/home/example/path
PORT=9999
HOST=localhost
MSGS_PER_CLIENTS=alpha=0 beta=55 delta=3
USE_EVEN=22
RETRIES=3
python:
@dataclasses.dataclass(frozen=True)
class Config:
FPATH: pathlib.Path
PORT: int
HOST: str
MSGS_PER_CLIENTS: Dict[str, int]
USE_EVEN: EvenState
RETRIES: Optional[int] = None
TIMEOUT: int = 30
def __post_init__(self) -> None:
if self.PORT <= 0:
raise ValueError("'PORT' is non-positive")
class EvenState:
def __init__(self, arg: str):
self.is_even = not bool(int(arg) % 2) # 1%2 -> 1 -> T -> F
def __repr__(self) -> str:
return f"EvenState(is_even={self.is_even})"
config = from_environment_as_dataclass(Config)
print(config)
stdout:
Config(
FPATH=PosixPath('/home/example/path'),
PORT=9999,
HOST='localhost',
MSGS_PER_CLIENTS={'alpha': 0, 'beta': 55, 'delta': 3},
USE_EVEN=EvenState(is_even=True),
RETRIES=3,
TIMEOUT=30)
Raises:
OSError - If a configuration value is requested and no default
value is provided, to indicate that the component's
configuration is incomplete due to missing data from
the OS.
ValueError - If an indicated value is not a legal value
TypeError - If an argument or indicated value is not a legal type
"""
```
#### `wipac_dev_tools.strtobool()`
```
def strtobool(string: str) -> bool:
"""Smart-cast a string to a bool using common-sense interpretations.
Unlike the since deprecated `distutils.util.strtobool`, this
returns an actual bool.
True: 'y', 'yes', 't', 'true', 'on', '1'
False: 'n', 'no', 'f', 'false', 'off', '0'
Raises:
ValueError: if the string does not match any of the about
"""
```
Raw data
{
"_id": null,
"home_page": null,
"name": "wipac-dev-tools",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.14,>=3.9",
"maintainer_email": null,
"keywords": "WIPAC, python, tools, utilities",
"author": null,
"author_email": "WIPAC Developers <developers@icecube.wisc.edu>",
"download_url": "https://files.pythonhosted.org/packages/ac/79/f099e069f0c4d8b93e064953fa464e9e3f8e2654341fd64e648830ed8081/wipac_dev_tools-1.13.0.tar.gz",
"platform": null,
"description": "<!--- Top of README Badges (automated) --->\n[![PyPI](https://img.shields.io/pypi/v/wipac-dev-tools)](https://pypi.org/project/wipac-dev-tools/) [![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/WIPACrepo/wipac-dev-tools?include_prereleases)](https://github.com/WIPACrepo/wipac-dev-tools/) [![Versions](https://img.shields.io/pypi/pyversions/wipac-dev-tools.svg)](https://pypi.org/project/wipac-dev-tools) [![PyPI - License](https://img.shields.io/pypi/l/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/blob/main/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/WIPACrepo/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aopen) [![GitHub pull requests](https://img.shields.io/github/issues-pr/WIPACrepo/wipac-dev-tools)](https://github.com/WIPACrepo/wipac-dev-tools/pulls?q=is%3Apr+sort%3Aupdated-desc+is%3Aopen)\n<!--- End of README Badges (automated) --->\n\n# wipac-dev-tools\n\nCommon, basic, and reusable development tools\n\n## Utilities\n\n### Logging Tools\n\n#### `wipac_dev_tools.logging_tools.set_level()`\n\n_Available for Python 3.6+_\n\n```\ndef set_level(\n level: LoggerLevel,\n first_party_loggers: Union[\n None, LogggerObjectOrName, List[LogggerObjectOrName]\n ] = None,\n third_party_level: LoggerLevel = \"WARNING\",\n future_third_parties: Union[None, str, List[str]] = None,\n specialty_loggers: Optional[Dict[LogggerObjectOrName, LoggerLevel]] = None,\n use_coloredlogs: bool = False,\n) -> None:\n \"\"\"Set the level of loggers of various precedence.\n\n The root logger and first-party logger(s) are set to the same level (`level`).\n\n Args:\n `level`\n the desired logging level (first-party), case-insensitive\n `first_party_loggers`\n a list (or a single instance) of `logging.Logger` or the loggers' names\n `third_party_level`\n the desired logging level for any other (currently) available loggers, case-insensitive\n `future_third_parties`\n additional third party logger(s) which have not yet been created (at call time)\n `specialty_loggers`\n additional loggers, each paired with a logging level, which are not\n considered first-party nor third-party loggers. **These have the highest precedence**\n `use_coloredlogs`\n if True, will import and use the `coloredlogs` package.\n This will set the logger format and use colored text.\n \"\"\"\n```\n\n#### `wipac_dev_tools.logging_tools.log_argparse_args()`\n\n_Available for Python 3.6+_\n\n```\ndef log_argparse_args(\n args: argparse.Namespace,\n logger: Union[None, str, logging.Logger] = None,\n level: LoggerLevel = \"WARNING\",\n) -> argparse.Namespace:\n \"\"\"Log the argparse args and their values at the given level.\n\n Return the args (Namespace) unchanged.\n\n Example:\n 2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING in_file: in_msg.pkl\n 2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING out_file: out_msg.pkl\n 2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING log: DEBUG\n 2022-05-13 22:37:21 fv-az136-643 my-logs[61] WARNING log_third_party: WARNING\n \"\"\"\n```\n\n### Environment Variable Tool(s)\n\n#### `wipac_dev_tools.from_environment()`\n\n_Available for Python 3.6+_\n\n```\ndef from_environment(keys: KeySpec) -> Dict[str, RetVal]:\n \"\"\"Obtain configuration values from the OS environment.\n\n Parsing Details:\n Types are inferred from the default values, and casted as such:\n `bool`: *(case-insensitive)*:\n - `True` => (\"y\", \"yes\", \"t\", \"true\", \"on\", or \"1\")\n - `False` => (\"n\", \"no\", \"f\", \"false\", \"off\", or \"0\")\n - `Error` => any other string\n `int`: normal cast (`int(str)`)\n `float`: normal cast (`float(str)`)\n `other`: no change (`str`)\n\n Arguments:\n keys - Specify the configuration values to obtain.\n\n This can be a string, specifying a single key, such as:\n\n config_dict = from_environment(\"LANGUAGE\")\n\n This can be a list of strings, specifying multiple keys,\n such as:\n\n config_dict = from_environment([\"HOME\", \"LANGUAGE\"])\n\n This can be a dictionary that provides some default values,\n and will accept overrides from the environment:\n\n default_config = {\n \"HOST\": \"localhost\",\n \"PORT\": 8080,\n \"REQUIRED_FROM_ENVIRONMENT\": None\n }\n config_dict = from_environment(default_config)\n\n Note in this case that if 'HOST' or 'PORT' were defined in the\n environment, those values would be returned in config_dict. If\n the values were not defined in the environment, the default values\n from default_config would be returned in config_dict.\n\n Also note, that if 'REQUIRED_FROM_ENVIRONMENT' is not defined,\n an OSError will be raised. The sentinel value of None indicates\n that the configuration parameter MUST be sourced from the\n environment.\n\n Returns:\n a dictionary mapping configuration keys to configuration values\n\n Raises:\n OSError - If a configuration value is requested and no default\n value is provided (via a dict), to indicate that the\n component's configuration is incomplete due to missing\n data from the OS.\n ValueError - If a type-indicated value is not a legal value\n \"\"\"\n```\n\n#### `wipac_dev_tools.from_environment_as_dataclass()`\n\n_Available for Python >=3.9_\n\n```\ndef from_environment_as_dataclass(\n dclass: Type[T],\n collection_sep: Optional[str] = None,\n dict_kv_joiner: str = \"=\",\n log_vars: Optional[logging_tools.LoggerLevel] = \"WARNING\",\n) -> T:\n \"\"\"Obtain configuration values from the OS environment formatted in a\n dataclass.\n\n Environment variables are matched to a dataclass field's name. The\n matching environment string is cast using the dataclass field's type\n (there are some special cases for built-in types, see below). Then,\n the values are used to create a dataclass instance. All normal\n dataclass init-behavior is expected, like required fields\n (positional arguments), optional fields with defaults, default\n factories, post-init processing, etc.\n\n If a field's type is a bool, `wipac_dev_tools.strtobool` is applied.\n\n If a field's type is a `list`, `dict`, `set`, `frozenset`, or\n an analogous type alias from the 'typing' module, then a conversion\n is made (see `collection_sep` and `dict_kv_joiner`). Sub-types\n are cast if using a typing-module type alias. The typing-module's\n alias types must resolve to `type` within 1 nesting (eg: List[bool]\n and Dict[int, float] are okay; List[Dict[int, float]] is not), or\n 2 if using 'Final' or 'Optional' (ex: Final[Dict[int, float]]).\n\n If a field's type is a class that accepts 1 argument, it is\n instantiated as such.\n\n Arguments:\n dclass - a (non-instantiated) dataclass, aka a type\n collection_sep - the delimiter to split collections on (\"1 2 5\")\n dict_kv_joiner - the delimiter that joins key-value pairs (\"a=1 b=2 c=1\")\n log_vars - what level to log the collected environment variables (set to `None` to not log)\n\n Returns:\n a dataclass instance mapping configuration keys to configuration values\n\n Example:\n env:\n FPATH=/home/example/path\n PORT=9999\n HOST=localhost\n MSGS_PER_CLIENTS=alpha=0 beta=55 delta=3\n USE_EVEN=22\n RETRIES=3\n\n python:\n @dataclasses.dataclass(frozen=True)\n class Config:\n FPATH: pathlib.Path\n PORT: int\n HOST: str\n MSGS_PER_CLIENTS: Dict[str, int]\n USE_EVEN: EvenState\n RETRIES: Optional[int] = None\n TIMEOUT: int = 30\n\n def __post_init__(self) -> None:\n if self.PORT <= 0:\n raise ValueError(\"'PORT' is non-positive\")\n\n class EvenState:\n def __init__(self, arg: str):\n self.is_even = not bool(int(arg) % 2) # 1%2 -> 1 -> T -> F\n def __repr__(self) -> str:\n return f\"EvenState(is_even={self.is_even})\"\n\n config = from_environment_as_dataclass(Config)\n print(config)\n\n stdout:\n Config(\n FPATH=PosixPath('/home/example/path'),\n PORT=9999,\n HOST='localhost',\n MSGS_PER_CLIENTS={'alpha': 0, 'beta': 55, 'delta': 3},\n USE_EVEN=EvenState(is_even=True),\n RETRIES=3,\n TIMEOUT=30)\n\n\n Raises:\n OSError - If a configuration value is requested and no default\n value is provided, to indicate that the component's\n configuration is incomplete due to missing data from\n the OS.\n ValueError - If an indicated value is not a legal value\n TypeError - If an argument or indicated value is not a legal type\n \"\"\"\n```\n\n#### `wipac_dev_tools.strtobool()`\n\n```\ndef strtobool(string: str) -> bool:\n \"\"\"Smart-cast a string to a bool using common-sense interpretations.\n\n Unlike the since deprecated `distutils.util.strtobool`, this\n returns an actual bool.\n\n True: 'y', 'yes', 't', 'true', 'on', '1'\n False: 'n', 'no', 'f', 'false', 'off', '0'\n\n Raises:\n ValueError: if the string does not match any of the about\n \"\"\"\n```\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2021 Wisconsin IceCube Particle Astrophysics Center Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "Common, basic, and reusable development tools",
"version": "1.13.0",
"project_urls": {
"Homepage": "https://pypi.org/project/wipac-dev-tools/",
"Source": "https://github.com/WIPACrepo/wipac-dev-tools",
"Tracker": "https://github.com/WIPACrepo/wipac-dev-tools/issues"
},
"split_keywords": [
"wipac",
" python",
" tools",
" utilities"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f5e698b7d2931aa16d2a89bb48e743c06fd8589427f1cf0b2c57bb37d467bb9b",
"md5": "46ad76daf6a38750ea77acbc24411a59",
"sha256": "39913c069099a66145d31945bb2254c9a3655142f745762a833a50e21d2e2a42"
},
"downloads": -1,
"filename": "wipac_dev_tools-1.13.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "46ad76daf6a38750ea77acbc24411a59",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.14,>=3.9",
"size": 21773,
"upload_time": "2024-10-09T18:22:09",
"upload_time_iso_8601": "2024-10-09T18:22:09.752984Z",
"url": "https://files.pythonhosted.org/packages/f5/e6/98b7d2931aa16d2a89bb48e743c06fd8589427f1cf0b2c57bb37d467bb9b/wipac_dev_tools-1.13.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ac79f099e069f0c4d8b93e064953fa464e9e3f8e2654341fd64e648830ed8081",
"md5": "a5303b5c8739dce02c7085d96c265c5f",
"sha256": "c86012027da4572f6eb1a2c91df28883d04c1a91940b416da929fc459256d77d"
},
"downloads": -1,
"filename": "wipac_dev_tools-1.13.0.tar.gz",
"has_sig": false,
"md5_digest": "a5303b5c8739dce02c7085d96c265c5f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.14,>=3.9",
"size": 24745,
"upload_time": "2024-10-09T18:22:10",
"upload_time_iso_8601": "2024-10-09T18:22:10.927677Z",
"url": "https://files.pythonhosted.org/packages/ac/79/f099e069f0c4d8b93e064953fa464e9e3f8e2654341fd64e648830ed8081/wipac_dev_tools-1.13.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-09 18:22:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "WIPACrepo",
"github_project": "wipac-dev-tools",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "wipac-dev-tools"
}