Name | python-utils JSON |
Version |
3.9.0
JSON |
| download |
home_page | https://github.com/WoLpH/python-utils |
Summary | Python Utils is a module with some convenient utilities not included with the standard Python install |
upload_time | 2024-09-25 02:14:59 |
maintainer | None |
docs_url | https://pythonhosted.org/python-utils/ |
author | Rick van Hattem |
requires_python | >3.9.0 |
license | BSD |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
|
Useful Python Utils
==============================================================================
.. image:: https://github.com/WoLpH/python-utils/actions/workflows/main.yml/badge.svg?branch=master
:target: https://github.com/WoLpH/python-utils/actions/workflows/main.yml
.. image:: https://coveralls.io/repos/WoLpH/python-utils/badge.svg?branch=master
:target: https://coveralls.io/r/WoLpH/python-utils?branch=master
Python Utils is a collection of small Python functions and
classes which make common patterns shorter and easier. It is by no means a
complete collection but it has served me quite a bit in the past and I will
keep extending it.
One of the libraries using Python Utils is Django Utils.
Documentation is available at: https://python-utils.readthedocs.org/en/latest/
Links
-----
- The source: https://github.com/WoLpH/python-utils
- Project page: https://pypi.python.org/pypi/python-utils
- Reporting bugs: https://github.com/WoLpH/python-utils/issues
- Documentation: https://python-utils.readthedocs.io/en/latest/
- My blog: https://wol.ph/
Security contact information
------------------------------------------------------------------------------
To report a security vulnerability, please use the
`Tidelift security contact <https://tidelift.com/security>`_.
Tidelift will coordinate the fix and disclosure.
Requirements for installing:
------------------------------------------------------------------------------
For the Python 3+ release (i.e. v3.0.0 or higher) there are no requirements.
For the Python 2 compatible version (v2.x.x) the `six` package is needed.
Installation:
------------------------------------------------------------------------------
The package can be installed through `pip` (this is the recommended method):
.. code-block:: bash
pip install python-utils
Or if `pip` is not available, `easy_install` should work as well:
.. code-block:: bash
easy_install python-utils
Or download the latest release from Pypi (https://pypi.python.org/pypi/python-utils) or Github.
Note that the releases on Pypi are signed with my GPG key (https://pgp.mit.edu/pks/lookup?op=vindex&search=0xE81444E9CE1F695D) and can be checked using GPG:
.. code-block:: bash
gpg --verify python-utils-<version>.tar.gz.asc python-utils-<version>.tar.gz
Quickstart
------------------------------------------------------------------------------
This module makes it easy to execute common tasks in Python scripts such as
converting text to numbers and making sure a string is in unicode or bytes
format.
Examples
------------------------------------------------------------------------------
Automatically converting a generator to a list, dict or other collections
using a decorator:
.. code-block:: pycon
>>> @decorators.listify()
... def generate_list():
... yield 1
... yield 2
... yield 3
...
>>> generate_list()
[1, 2, 3]
>>> @listify(collection=dict)
... def dict_generator():
... yield 'a', 1
... yield 'b', 2
>>> dict_generator()
{'a': 1, 'b': 2}
Retrying until timeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To easily retry a block of code with a configurable timeout, you can use the
`time.timeout_generator`:
.. code-block:: pycon
>>> for i in time.timeout_generator(10):
... try:
... # Run your code here
... except Exception as e:
... # Handle the exception
Formatting of timestamps, dates and times
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Easy formatting of timestamps and calculating the time since:
.. code-block:: pycon
>>> time.format_time('1')
'0:00:01'
>>> time.format_time(1.234)
'0:00:01'
>>> time.format_time(1)
'0:00:01'
>>> time.format_time(datetime.datetime(2000, 1, 2, 3, 4, 5, 6))
'2000-01-02 03:04:05'
>>> time.format_time(datetime.date(2000, 1, 2))
'2000-01-02'
>>> time.format_time(datetime.timedelta(seconds=3661))
'1:01:01'
>>> time.format_time(None)
'--:--:--'
>>> formatters.timesince(now)
'just now'
>>> formatters.timesince(now - datetime.timedelta(seconds=1))
'1 second ago'
>>> formatters.timesince(now - datetime.timedelta(seconds=2))
'2 seconds ago'
>>> formatters.timesince(now - datetime.timedelta(seconds=60))
'1 minute ago'
Converting your test from camel-case to underscores:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: pycon
>>> camel_to_underscore('SpamEggsAndBacon')
'spam_eggs_and_bacon'
Attribute setting decorator. Very useful for the Django admin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A convenient decorator to set function attributes using a decorator:
.. code-block:: pycon
You can use:
>>> @decorators.set_attributes(short_description='Name')
... def upper_case_name(self, obj):
... return ("%s %s" % (obj.first_name, obj.last_name)).upper()
Instead of:
>>> def upper_case_name(obj):
... return ("%s %s" % (obj.first_name, obj.last_name)).upper()
>>> upper_case_name.short_description = 'Name'
This can be very useful for the Django admin as it allows you to have all
metadata in one place.
Scaling numbers between ranges
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: pycon
>>> converters.remap(500, old_min=0, old_max=1000, new_min=0, new_max=100)
50
# Or with decimals:
>>> remap(decimal.Decimal('250.0'), 0.0, 1000.0, 0.0, 100.0)
Decimal('25.0')
Get the screen/window/terminal size in characters:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: pycon
>>> terminal.get_terminal_size()
(80, 24)
That method supports IPython and Jupyter as well as regular shells, using
`blessings` and other modules depending on what is available.
Extracting numbers from nearly every string:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: pycon
>>> converters.to_int('spam15eggs')
15
>>> converters.to_int('spam')
0
>>> number = converters.to_int('spam', default=1)
1
Doing a global import of all the modules in a package programmatically:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To do a global import programmatically you can use the `import_global`
function. This effectively emulates a `from ... import *`
.. code-block:: python
from python_utils.import_ import import_global
# The following is the equivalent of `from some_module import *`
import_global('some_module')
Automatically named logger for classes:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Or add a correclty named logger to your classes which can be easily accessed:
.. code-block:: python
class MyClass(Logged):
def __init__(self):
Logged.__init__(self)
my_class = MyClass()
# Accessing the logging method:
my_class.error('error')
# With formatting:
my_class.error('The logger supports %(formatting)s',
formatting='named parameters')
# Or to access the actual log function (overwriting the log formatting can
# be done n the log method)
import logging
my_class.log(logging.ERROR, 'log')
Alternatively loguru is also supported. It is largely a drop-in replacement for the logging module which is a bit more convenient to configure:
First install the extra loguru package:
.. code-block:: bash
pip install 'python-utils[loguru]'
.. code-block:: python
class MyClass(Logurud):
...
Now you can use the `Logurud` class to make functions such as `self.info()`
available. The benefit of this approach is that you can add extra context or
options to you specific loguru instance (i.e. `self.logger`):
Convenient type aliases and some commonly used types:
.. code-block:: python
# For type hinting scopes such as locals/globals/vars
Scope = Dict[str, Any]
OptionalScope = O[Scope]
# Note that Number is only useful for extra clarity since float
# will work for both int and float in practice.
Number = U[int, float]
DecimalNumber = U[Number, decimal.Decimal]
# To accept an exception or list of exceptions
ExceptionType = Type[Exception]
ExceptionsType = U[Tuple[ExceptionType, ...], ExceptionType]
# Matching string/bytes types:
StringTypes = U[str, bytes]
Raw data
{
"_id": null,
"home_page": "https://github.com/WoLpH/python-utils",
"name": "python-utils",
"maintainer": null,
"docs_url": "https://pythonhosted.org/python-utils/",
"requires_python": ">3.9.0",
"maintainer_email": null,
"keywords": null,
"author": "Rick van Hattem",
"author_email": "Wolph@wol.ph",
"download_url": "https://files.pythonhosted.org/packages/33/99/fd1e3f80357dd88378281013ae7040a443de395bb0855bf17cbb828488d1/python_utils-3.9.0.tar.gz",
"platform": null,
"description": "Useful Python Utils\n==============================================================================\n\n.. image:: https://github.com/WoLpH/python-utils/actions/workflows/main.yml/badge.svg?branch=master\n :target: https://github.com/WoLpH/python-utils/actions/workflows/main.yml\n\n.. image:: https://coveralls.io/repos/WoLpH/python-utils/badge.svg?branch=master\n :target: https://coveralls.io/r/WoLpH/python-utils?branch=master\n\nPython Utils is a collection of small Python functions and\nclasses which make common patterns shorter and easier. It is by no means a\ncomplete collection but it has served me quite a bit in the past and I will\nkeep extending it.\n\nOne of the libraries using Python Utils is Django Utils.\n\nDocumentation is available at: https://python-utils.readthedocs.org/en/latest/\n\nLinks\n-----\n\n - The source: https://github.com/WoLpH/python-utils\n - Project page: https://pypi.python.org/pypi/python-utils\n - Reporting bugs: https://github.com/WoLpH/python-utils/issues\n - Documentation: https://python-utils.readthedocs.io/en/latest/\n - My blog: https://wol.ph/\n\nSecurity contact information\n------------------------------------------------------------------------------\n\nTo report a security vulnerability, please use the\n`Tidelift security contact <https://tidelift.com/security>`_.\nTidelift will coordinate the fix and disclosure.\n\nRequirements for installing:\n------------------------------------------------------------------------------\n\nFor the Python 3+ release (i.e. v3.0.0 or higher) there are no requirements.\nFor the Python 2 compatible version (v2.x.x) the `six` package is needed.\n\nInstallation:\n------------------------------------------------------------------------------\n\nThe package can be installed through `pip` (this is the recommended method):\n\n.. code-block:: bash\n\n pip install python-utils\n \nOr if `pip` is not available, `easy_install` should work as well:\n\n.. code-block:: bash\n\n easy_install python-utils\n \nOr download the latest release from Pypi (https://pypi.python.org/pypi/python-utils) or Github.\n\nNote that the releases on Pypi are signed with my GPG key (https://pgp.mit.edu/pks/lookup?op=vindex&search=0xE81444E9CE1F695D) and can be checked using GPG:\n\n.. code-block:: bash\n\n gpg --verify python-utils-<version>.tar.gz.asc python-utils-<version>.tar.gz\n\nQuickstart\n------------------------------------------------------------------------------\n\nThis module makes it easy to execute common tasks in Python scripts such as\nconverting text to numbers and making sure a string is in unicode or bytes\nformat.\n\nExamples\n------------------------------------------------------------------------------\n\nAutomatically converting a generator to a list, dict or other collections\nusing a decorator:\n\n.. code-block:: pycon\n\n >>> @decorators.listify()\n ... def generate_list():\n ... yield 1\n ... yield 2\n ... yield 3\n ...\n >>> generate_list()\n [1, 2, 3]\n\n >>> @listify(collection=dict)\n ... def dict_generator():\n ... yield 'a', 1\n ... yield 'b', 2\n\n >>> dict_generator()\n {'a': 1, 'b': 2}\n\nRetrying until timeout\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo easily retry a block of code with a configurable timeout, you can use the\n`time.timeout_generator`:\n\n.. code-block:: pycon\n\n >>> for i in time.timeout_generator(10):\n ... try:\n ... # Run your code here\n ... except Exception as e:\n ... # Handle the exception\n\nFormatting of timestamps, dates and times\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nEasy formatting of timestamps and calculating the time since:\n\n.. code-block:: pycon\n\n >>> time.format_time('1')\n '0:00:01'\n >>> time.format_time(1.234)\n '0:00:01'\n >>> time.format_time(1)\n '0:00:01'\n >>> time.format_time(datetime.datetime(2000, 1, 2, 3, 4, 5, 6))\n '2000-01-02 03:04:05'\n >>> time.format_time(datetime.date(2000, 1, 2))\n '2000-01-02'\n >>> time.format_time(datetime.timedelta(seconds=3661))\n '1:01:01'\n >>> time.format_time(None)\n '--:--:--'\n\n >>> formatters.timesince(now)\n 'just now'\n >>> formatters.timesince(now - datetime.timedelta(seconds=1))\n '1 second ago'\n >>> formatters.timesince(now - datetime.timedelta(seconds=2))\n '2 seconds ago'\n >>> formatters.timesince(now - datetime.timedelta(seconds=60))\n '1 minute ago'\n\nConverting your test from camel-case to underscores:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: pycon\n\n >>> camel_to_underscore('SpamEggsAndBacon')\n 'spam_eggs_and_bacon'\n\nAttribute setting decorator. Very useful for the Django admin\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nA convenient decorator to set function attributes using a decorator:\n\n.. code-block:: pycon\n\n You can use:\n >>> @decorators.set_attributes(short_description='Name')\n ... def upper_case_name(self, obj):\n ... return (\"%s %s\" % (obj.first_name, obj.last_name)).upper()\n\n Instead of:\n >>> def upper_case_name(obj):\n ... return (\"%s %s\" % (obj.first_name, obj.last_name)).upper()\n\n >>> upper_case_name.short_description = 'Name'\n\nThis can be very useful for the Django admin as it allows you to have all\nmetadata in one place.\n\nScaling numbers between ranges\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: pycon\n\n >>> converters.remap(500, old_min=0, old_max=1000, new_min=0, new_max=100)\n 50\n\n # Or with decimals:\n >>> remap(decimal.Decimal('250.0'), 0.0, 1000.0, 0.0, 100.0)\n Decimal('25.0')\n\nGet the screen/window/terminal size in characters:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: pycon\n\n >>> terminal.get_terminal_size()\n (80, 24)\n\nThat method supports IPython and Jupyter as well as regular shells, using\n`blessings` and other modules depending on what is available.\n\nExtracting numbers from nearly every string:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block:: pycon\n\n >>> converters.to_int('spam15eggs')\n 15\n >>> converters.to_int('spam')\n 0\n >>> number = converters.to_int('spam', default=1)\n 1\n\nDoing a global import of all the modules in a package programmatically:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo do a global import programmatically you can use the `import_global`\nfunction. This effectively emulates a `from ... import *`\n\n.. code-block:: python\n\n from python_utils.import_ import import_global\n\n # The following is the equivalent of `from some_module import *`\n import_global('some_module')\n\nAutomatically named logger for classes:\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOr add a correclty named logger to your classes which can be easily accessed:\n\n.. code-block:: python\n\n class MyClass(Logged):\n def __init__(self):\n Logged.__init__(self)\n\n my_class = MyClass()\n\n # Accessing the logging method:\n my_class.error('error')\n\n # With formatting:\n my_class.error('The logger supports %(formatting)s',\n formatting='named parameters')\n\n # Or to access the actual log function (overwriting the log formatting can\n # be done n the log method)\n import logging\n my_class.log(logging.ERROR, 'log')\n\nAlternatively loguru is also supported. It is largely a drop-in replacement for the logging module which is a bit more convenient to configure:\n\nFirst install the extra loguru package:\n\n.. code-block:: bash\n\n pip install 'python-utils[loguru]'\n\n.. code-block:: python\n\n class MyClass(Logurud):\n ...\n\nNow you can use the `Logurud` class to make functions such as `self.info()`\navailable. The benefit of this approach is that you can add extra context or\noptions to you specific loguru instance (i.e. `self.logger`):\n\nConvenient type aliases and some commonly used types:\n\n.. code-block:: python\n\n # For type hinting scopes such as locals/globals/vars\n Scope = Dict[str, Any]\n OptionalScope = O[Scope]\n\n # Note that Number is only useful for extra clarity since float\n # will work for both int and float in practice.\n Number = U[int, float]\n DecimalNumber = U[Number, decimal.Decimal]\n\n # To accept an exception or list of exceptions\n ExceptionType = Type[Exception]\n ExceptionsType = U[Tuple[ExceptionType, ...], ExceptionType]\n\n # Matching string/bytes types:\n StringTypes = U[str, bytes]\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "Python Utils is a module with some convenient utilities not included with the standard Python install",
"version": "3.9.0",
"project_urls": {
"Homepage": "https://github.com/WoLpH/python-utils"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "17e7200045de1f41ad74915a334f7c2aac54d2d6f4b89643a53e1062cde4895b",
"md5": "9e692aecc142b97b665de1ecd43ae7f6",
"sha256": "a7719a5ef4bae7360d2a15c13b08c4e3c3e39b9df19bd16f119ff8d0cfeaafb7"
},
"downloads": -1,
"filename": "python_utils-3.9.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "9e692aecc142b97b665de1ecd43ae7f6",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">3.9.0",
"size": 32085,
"upload_time": "2024-09-25T02:14:56",
"upload_time_iso_8601": "2024-09-25T02:14:56.486911Z",
"url": "https://files.pythonhosted.org/packages/17/e7/200045de1f41ad74915a334f7c2aac54d2d6f4b89643a53e1062cde4895b/python_utils-3.9.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3399fd1e3f80357dd88378281013ae7040a443de395bb0855bf17cbb828488d1",
"md5": "38155c9dd3f4f1ce51819449d74be1d2",
"sha256": "3689556884e3ae53aec5a4c9f17b36e752a3e93a7ba2768c6553fc4dd6fa70ef"
},
"downloads": -1,
"filename": "python_utils-3.9.0.tar.gz",
"has_sig": false,
"md5_digest": "38155c9dd3f4f1ce51819449d74be1d2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">3.9.0",
"size": 35352,
"upload_time": "2024-09-25T02:14:59",
"upload_time_iso_8601": "2024-09-25T02:14:59.033579Z",
"url": "https://files.pythonhosted.org/packages/33/99/fd1e3f80357dd88378281013ae7040a443de395bb0855bf17cbb828488d1/python_utils-3.9.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-25 02:14:59",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "WoLpH",
"github_project": "python-utils",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"requirements": [],
"tox": true,
"lcname": "python-utils"
}