pyutilities 2.4.2__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {pyutilities-2.4.2 → pyutilities-2.5.0}/PKG-INFO +29 -33
  2. pyutilities-2.5.0/README.md +42 -0
  3. {pyutilities-2.4.2 → pyutilities-2.5.0}/pyproject.toml +12 -12
  4. pyutilities-2.5.0/src/pyutilities/utils/datetime_utils.py +148 -0
  5. pyutilities-2.5.0/src/pyutilities/utils/structures.py +62 -0
  6. pyutilities-2.4.2/docs/README-PUB.md +0 -46
  7. pyutilities-2.4.2/src/pyutilities/utils/datetime_utils.py +0 -78
  8. {pyutilities-2.4.2 → pyutilities-2.5.0}/LICENSE +0 -0
  9. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/__init__.py +0 -0
  10. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/cli/__init__.py +0 -0
  11. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/cli/fedit.py +0 -0
  12. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/cli/pyutils.py +0 -0
  13. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/config/__init__.py +0 -0
  14. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/config/configuration.py +0 -0
  15. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/defaults.py +0 -0
  16. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/exception.py +0 -0
  17. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/io/__init__.py +0 -0
  18. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/io/io_utils.py +0 -0
  19. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/log/__init__.py +0 -0
  20. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/log/log_manager.py +0 -0
  21. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/logging.py +0 -0
  22. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/sys/__init__.py +0 -0
  23. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/sys/sys_utils.py +0 -0
  24. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/utils/__init__.py +0 -0
  25. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/utils/common_utils.py +0 -0
  26. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/utils/decorators.py +0 -0
  27. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/utils/lambdas.py +0 -0
  28. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/utils/string_utils.py +0 -0
  29. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/web/__init__.py +0 -0
  30. {pyutilities-2.4.2 → pyutilities-2.5.0}/src/pyutilities/web/http_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyutilities
3
- Version: 2.4.2
3
+ Version: 2.5.0
4
4
  Summary: PyUtilities :: Useful python 3+ utilities library for various use cases.
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -28,13 +28,13 @@ Requires-Dist: loguru (==0.7.3)
28
28
  Requires-Dist: markdown (>=3.7,<4.0)
29
29
  Requires-Dist: marshmallow (>=4.1,<5.0)
30
30
  Requires-Dist: openpyxl (==3.1.5)
31
- Requires-Dist: paramiko (==4.*)
31
+ Requires-Dist: paramiko (==5.*)
32
32
  Requires-Dist: pendulum (>=3.2,<4.0)
33
33
  Requires-Dist: prettytable (>=3.14,<4.0)
34
34
  Requires-Dist: prettytable (>=3.17,<4.0)
35
35
  Requires-Dist: pydantic (>=2.12.5,<3.0.0)
36
36
  Requires-Dist: pydantic-settings (==2.*)
37
- Requires-Dist: pydantic-yaml (==1.*)
37
+ Requires-Dist: pydantic-yaml (>=1.6,<2.0)
38
38
  Requires-Dist: pyfiglet (>=1.0,<2.0)
39
39
  Requires-Dist: python-dateutil (>=2.9,<3.0)
40
40
  Requires-Dist: python-dotenv (>=1.2,<2.0)
@@ -42,7 +42,7 @@ Requires-Dist: pytz (==2026.*)
42
42
  Requires-Dist: pyyaml (==6.*)
43
43
  Requires-Dist: requests (>=2.32,<3.0)
44
44
  Requires-Dist: rich-pyfiglet (>=1.0,<2.0)
45
- Requires-Dist: ruamel.yaml (==0.*)
45
+ Requires-Dist: ruamel.yaml (==0.18.*)
46
46
  Requires-Dist: urllib3 (>=2.6,<3.0)
47
47
  Requires-Dist: xlrd (>=2.0.1,<2.1.0)
48
48
  Requires-Dist: xlwings (>=0.35,<1.0)
@@ -53,50 +53,46 @@ Project-URL: Homepage, https://pypi.org/project/pyutilities
53
53
  Project-URL: Repository, https://github.com/dmitry-ed-gusev/pyutilities
54
54
  Description-Content-Type: text/markdown
55
55
 
56
- # Python Utilities Library
56
+ # Python Utilities Library (PyUtilities)
57
57
 
58
- Version 2.4.2, 2018 - 2026, Dmitrii Gusev
59
- *Last update: 15.05.2026*
58
+ **Dmitrii Gusev, 2018-2026.**
60
59
 
61
60
  ## Project Description
62
61
 
63
- Useful utilities functions for various needs for the python 3.10+. Containing 'general purpose' functions.
62
+ Useful utilities functions for various needs for the **python 3.10+**. Containing many 'general purpose' functions for various areas. Using of this library may simplify/help with the development in various 'common' tasks.
64
63
 
65
- ## Versions history
64
+ ## Installation
66
65
 
67
- ### 2.4.0/2.4.1/2.4.2
66
+ There are no special pre-requisites for the library to be installed, except **python 3.10+**
67
+ In order to install this library, use the following command:
68
68
 
69
- - many refactorings and minor code improvements
70
- - overall tests coverage now > 50%, working on improvements :)
71
- - added new date/time function, several decorators
72
- - added several useful string functions
73
- - added LoggingManager component for loguru simple configuration
74
- - v.2.4.1/v.2.4.2 - minor docs fixes
69
+ ```bash
70
+ pip install pyutilities
71
+ ```
75
72
 
76
- ### 2.3.0
73
+ **Note: versions 2.1.0, 2.1.1 are intended only for the python version = 3.10 and can be installed only for it!**
77
74
 
78
- Intermediate version with improvements/refactorings.
75
+ ## Tech Details
79
76
 
80
- ### 2.2.0
77
+ ### Project modules
81
78
 
82
- Added several new functions - see sources.
79
+ - **cli** - Command Line Integration/Interface - module is under development now :)
80
+ - **config** - configuration module, can be used anywhere
81
+ - **io** - input/output utilities
82
+ - **log** - logging helper classes
83
+ - **sys** - system modules
84
+ - **utils** - various common utilities (common, strings, dates, structures, etc.)
85
+ - **web** - web client, simple web/http server
83
86
 
84
- ### 2.1.2
87
+ ### Library Usage Examples
85
88
 
86
- Major release with complete set of useful 'general purpose' functions. Documentation 'is coming'...
89
+ See folder **[examples]** in the project root repository.
87
90
 
88
- **Warning! Versions 2.1.0, 2.1.1 are intended only for the python version = 3.10 and can be installed only for it!**
91
+ ### Development Environment Setup
89
92
 
90
- ### Versions before 2.x.x
93
+ There are various shell scripts in the root of the project repository, all of them are well-commented - see there.
91
94
 
92
- **It is strongly recommended: don't use versions prior to the 2.x.x!**
95
+ ### Publishing to PyPi Registry
93
96
 
94
- Main properties of the previous library versions:
95
-
96
- - set of the 'minor' and 'experimental' releases
97
- - various set of functions without consistency
98
- - many 'experimental' functions without proper testing
99
- - a lot of unnecessary code
100
- - experiments with building/dependencies management tools - no tool, pipenv poetry
101
- - unstable list of dependencies with obsolete versions
97
+ Look at the script **_deploy.sh** in the project repo root folder.
102
98
 
@@ -0,0 +1,42 @@
1
+ # Python Utilities Library (PyUtilities)
2
+
3
+ **Dmitrii Gusev, 2018-2026.**
4
+
5
+ ## Project Description
6
+
7
+ Useful utilities functions for various needs for the **python 3.10+**. Containing many 'general purpose' functions for various areas. Using of this library may simplify/help with the development in various 'common' tasks.
8
+
9
+ ## Installation
10
+
11
+ There are no special pre-requisites for the library to be installed, except **python 3.10+**
12
+ In order to install this library, use the following command:
13
+
14
+ ```bash
15
+ pip install pyutilities
16
+ ```
17
+
18
+ **Note: versions 2.1.0, 2.1.1 are intended only for the python version = 3.10 and can be installed only for it!**
19
+
20
+ ## Tech Details
21
+
22
+ ### Project modules
23
+
24
+ - **cli** - Command Line Integration/Interface - module is under development now :)
25
+ - **config** - configuration module, can be used anywhere
26
+ - **io** - input/output utilities
27
+ - **log** - logging helper classes
28
+ - **sys** - system modules
29
+ - **utils** - various common utilities (common, strings, dates, structures, etc.)
30
+ - **web** - web client, simple web/http server
31
+
32
+ ### Library Usage Examples
33
+
34
+ See folder **[examples]** in the project root repository.
35
+
36
+ ### Development Environment Setup
37
+
38
+ There are various shell scripts in the root of the project repository, all of them are well-commented - see there.
39
+
40
+ ### Publishing to PyPi Registry
41
+
42
+ Look at the script **_deploy.sh** in the project repo root folder.
@@ -8,7 +8,7 @@
8
8
  # - most of modules should be typed (used mypy stubs libraries)
9
9
  #
10
10
  # Created: Dmitrii Gusev, 30.05.2025
11
- # Modified: Dmitrii Gusev, 15.05.2026
11
+ # Modified: Dmitrii Gusev, 25.05.2026
12
12
  #
13
13
  ####################################################################################################
14
14
 
@@ -20,13 +20,13 @@ build-backend = "poetry.core.masonry.api"
20
20
  # -- project / poetry utility meta-information
21
21
  [project]
22
22
  name = "pyutilities"
23
- version = "2.4.2"
23
+ version = "2.5.0"
24
24
  description = "PyUtilities :: Useful python 3+ utilities library for various use cases."
25
25
  authors = [
26
26
  {name = "Dmitrii Gusev", email = "dmitry.ed.gusev@gmail.com"},
27
27
  ]
28
28
  license = "MIT"
29
- readme = "docs/README-PUB.md"
29
+ readme = "README.md"
30
30
  requires-python = ">=3.10,<4"
31
31
  keywords = [
32
32
  "Python Utilities", "Useful Functions", "String Utilities", "CLI Functions", "toolset", "library",
@@ -63,15 +63,15 @@ dependencies = [
63
63
 
64
64
  # -- data validation and marshalling (JSON/YAML) --
65
65
  "pydantic (>=2.12.5,<3.0.0)",
66
- "pydantic-yaml ==1.*",
66
+ "pydantic-yaml ~=1.6",
67
67
  "pydantic-settings ==2.*",
68
68
  "marshmallow ~=4.1",
69
69
  "pyyaml ==6.*",
70
- "ruamel.yaml ==0.*",
70
+ "ruamel.yaml ==0.18.*",
71
71
 
72
72
  # -- technical libraries
73
73
  "urllib3~=2.6", # - allowed: >=2.3.0 <3.0.0
74
- "paramiko==4.*",
74
+ "paramiko ==5.*",
75
75
  "requests~=2.32", # - allowed: >=2.32.0 <3.0.0
76
76
  "markdown~=3.7", # - allowed: >=3.7.0 <4.0.0
77
77
  "prettytable~=3.14", # - allowed: >=3.14.0 <4.0.0
@@ -114,7 +114,7 @@ dev = [
114
114
  "hypothesis ==6.*",
115
115
 
116
116
  # -- typing libraries + typing stubs for runtime dependencies --
117
- "mypy ==1.*", # - typing library
117
+ "mypy ==2.*", # - typing library
118
118
  "types-six ==1.*",
119
119
  "types-mock ==5.*",
120
120
  "types-paramiko ==4.*",
@@ -150,7 +150,7 @@ dev = [
150
150
  "responses ==0.*", # - used by many testing/code quality libraries
151
151
 
152
152
  # -- readline module depending on the platform
153
- "pyreadline3 ==3.5.4 ; sys_platform == 'win32' or sys_platform == 'cygwin'",
153
+ "pyreadline3 ==3.* ; sys_platform == 'win32' or sys_platform == 'cygwin'",
154
154
  "gnureadline ==8.2.13 ; sys_platform != 'win32'"
155
155
 
156
156
  ]
@@ -165,11 +165,11 @@ research = [ # - research dependencies (Jupyter, etc.)
165
165
  packages = [{include = "pyutilities", from = "src"}]
166
166
 
167
167
  # -- poetry :: source repositories setup
168
- [[tool.poetry.source]]
169
- name = "severstal_repo"
170
- url = "https://repo.severstal.severstalgroup.com/artifactory/api/pypi/pypi/simple/"
168
+ # [[tool.poetry.source]]
169
+ # name = "severstal_repo"
170
+ # url = "https://repo.severstal.severstalgroup.com/artifactory/api/pypi/pypi/simple/"
171
171
  # priority = "primary" # - primary packages source
172
- priority = "supplemental" # - packages source will be used when primary is not available...
172
+ # priority = "supplemental" # - packages source will be used when primary is not available...
173
173
 
174
174
  [tool.poetry.dependencies]
175
175
  python = ">=3.10,<4"
@@ -0,0 +1,148 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Useful date/time utilities and functions.
5
+
6
+ Created: Dmitrii Gusev, 22.03.2026
7
+ Modified: Dmitrii Gusev, 25.05.2026
8
+ """
9
+
10
+ import calendar
11
+ import logging
12
+ from datetime import datetime, timedelta, timezone
13
+ from functools import lru_cache
14
+
15
+ from pyutilities.defaults import MSG_MODULE_ISNT_RUNNABLE
16
+
17
+ # DATETIME :: timezones defaults
18
+ MSK_TIMEZONE: timezone = timezone(timedelta(hours=3), name="Moscow Timezone (GMT+3)")
19
+ MSK_TIMEZONE_NAME: str = "Europe/Moscow"
20
+ # - CACHE :: cache setup (size) for cached functions/methods
21
+ LRU_CACHE_SIZE: int = 128
22
+
23
+
24
+ log = logging.getLogger(__name__)
25
+ log.addHandler(logging.NullHandler())
26
+
27
+
28
+ def get_timestamp(
29
+ current_timezone: timezone = MSK_TIMEZONE,
30
+ days: float = 0,
31
+ hours: float = 0,
32
+ minutes: float = 0,
33
+ seconds: float = 0,
34
+ ) -> datetime:
35
+ """Return timestamp: now (in the default timezone) +/- the specified time delta in hours / minutes /
36
+ seconds. Default timezone can be changed by the function argument."""
37
+
38
+ return datetime.now(current_timezone) + timedelta(
39
+ days=days, hours=hours, minutes=minutes, seconds=seconds
40
+ )
41
+
42
+
43
+ @lru_cache(maxsize=LRU_CACHE_SIZE)
44
+ def get_timestampc(
45
+ current_timezone: timezone = MSK_TIMEZONE,
46
+ days: float = 0,
47
+ hours: float = 0,
48
+ minutes: float = 0,
49
+ seconds: float = 0,
50
+ ) -> datetime:
51
+ """CACHED. Cached version of the get_timestamp() method."""
52
+
53
+ return get_timestamp(current_timezone, days, hours, minutes, seconds)
54
+
55
+
56
+ def get_dates_range_before_date(date: datetime, tzinfo: timezone) -> tuple[int, int]:
57
+ """Generates two dates range - date_from/date_to for the time period 'before today' - from the 1st day
58
+ of the current month till the today - 1 day (current month). In case today is 1st day - range for the
59
+ whole previous month, if today is 01.01.XXXX - range for 01.12.XXXX-1 - 31.12.XXXX-1.
60
+ """
61
+
62
+ log.debug("get_dates_range_before_date(): the date [%s].", date)
63
+
64
+ tstamp_from: int = 0
65
+ tstamp_to: int = 0
66
+
67
+ if date: # if date is OK (not empty/None)
68
+
69
+ # - processing and calculating dates
70
+ if date.day == 1: # today - 1st day of month, we need report for the previous month
71
+
72
+ if date.month == 1: # we are at 01.01.XXXX - we need report for Dec.XXXX - 1
73
+
74
+ date_from = datetime(date.year - 1, 12, 1, tzinfo=tzinfo) # from: 01 Dec Year-1 (prev. year)
75
+ date_to = datetime(date.year - 1, 12, 31, tzinfo=tzinfo) # to: 31 Dec Year-1 (prev. year)
76
+
77
+ else: # we are at 01.XX.XXXX - we need report for previous month
78
+
79
+ # from: 01 Month-1 Year
80
+ date_from = datetime(date.year, date.month - 1, 1, tzinfo=tzinfo)
81
+ # last day of the previous month
82
+ _, last_day = calendar.monthrange(date.year, date.month - 1)
83
+ # to: Last Day Month-1 Year
84
+ date_to = datetime(date.year, date.month - 1, last_day, tzinfo=tzinfo)
85
+
86
+ else: # today isn't the 1st, we need report from 1st till yesterday
87
+
88
+ date_from = datetime(date.year, date.month, 1, tzinfo=tzinfo) # from: 01 Month Year
89
+ date_to = datetime(date.year, date.month, date.day - 1, tzinfo=tzinfo) # to: Day-1 Month Year
90
+
91
+ # - final date/time - date from: XX.XX.XX 00:00:00
92
+ tstamp_from = int(
93
+ datetime(
94
+ date_from.year, date_from.month, date_from.day, hour=0, minute=0, second=0, tzinfo=tzinfo
95
+ ).timestamp()
96
+ )
97
+ # - final date/time - # date to: XX.XX.XXXX 23:59:59
98
+ tstamp_to = int(
99
+ datetime(
100
+ date_to.year, date_to.month, date_to.day, hour=23, minute=59, second=59, tzinfo=tzinfo
101
+ ).timestamp()
102
+ )
103
+
104
+ log.debug("Timestamps for [%s]: from [%s], to [%s].", date, tstamp_from, tstamp_to)
105
+
106
+ # - return the tuple of values
107
+ return (tstamp_from, tstamp_to)
108
+
109
+
110
+ @lru_cache(maxsize=LRU_CACHE_SIZE)
111
+ def get_dates_range_before_datec(date: datetime, tzinfo: timezone) -> tuple[int, int]:
112
+ """CACHED. Cached version of the get_dates_range_before_date()."""
113
+
114
+ return get_dates_range_before_date(date, tzinfo)
115
+
116
+
117
+ def human_readable_duration_seconds(duration_seconds):
118
+ """Convert duration in seconds into human-readable string-duration."""
119
+
120
+ days = duration_seconds // (24 * 3600)
121
+ hours = (duration_seconds % (24 * 3600)) // 3600
122
+ minutes = (duration_seconds % (24 * 3600)) % 3600 // 60
123
+ seconds = duration_seconds % 3600 % 60
124
+
125
+ result = ""
126
+ if days > 0:
127
+ result += f"{days} д. "
128
+ if hours > 0:
129
+ result += f"{hours} ч. "
130
+ if minutes > 0:
131
+ result += f"{minutes:02d} мин. "
132
+ result += f"{seconds:02d} сек."
133
+ result = result.strip()
134
+
135
+ log.debug("Converted duration: [%s] into readable str: [%s].", duration_seconds, result)
136
+
137
+ return result
138
+
139
+
140
+ @lru_cache(maxsize=LRU_CACHE_SIZE)
141
+ def human_readable_duration_secondsc(duration_seconds):
142
+ """CACHED. Cached version of the human_readable_duration_seconds() method."""
143
+
144
+ return human_readable_duration_seconds(duration_seconds)
145
+
146
+
147
+ if __name__ == "__main__":
148
+ print(MSG_MODULE_ISNT_RUNNABLE)
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Structures module.
5
+
6
+ Created: Dmitrii Gusev, 21.05.2026
7
+ Modified: Dmitrii Gusev, 24.05.2026
8
+ """
9
+
10
+ from collections import defaultdict
11
+
12
+ from pyutilities.utils.string_utils import is_empty
13
+
14
+
15
+ def _defaultdict_factory(key: str):
16
+ """Return different default types for the defaultdict based on the key prefix.
17
+ This function is used a s a default factory for the class KeyAwareDefaultDict - see below.
18
+ """
19
+
20
+ if isinstance(key, str) and not is_empty(key):
21
+
22
+ if key.startswith("count_"): # int type
23
+ return 0
24
+
25
+ if key.startswith("str_"): # string type
26
+ return ""
27
+
28
+ if key.startswith("items_"): # list type
29
+ return []
30
+
31
+ if key.startswith("set_"): # set type
32
+ return set()
33
+
34
+ if key.startswith("dict_"): # dictionary type
35
+ return {}
36
+
37
+ # unknown type - fallback for unknown keys
38
+ return None
39
+
40
+
41
+ class KeyAwareDefaultDict(defaultdict): # type: ignore[type-arg]
42
+ """Extension of the default dictionary in python - 'key aware default dictionary', implementing
43
+ different types of the dictionary values, depending on the dictionary keys prefixes.
44
+ Prefixes are:
45
+ - count_* - int type
46
+ - str_* - str type
47
+ - items_* - list type
48
+ - set_* - set type
49
+ - dict_* - dict type
50
+ Usage example:
51
+ dynamic_dict = KeyAwareDefaultDict() # option I - default factory (see above)
52
+ dynamic_dict = KeyAwareDefaultDict(default_factory) # option II - use your custom factory function
53
+ """
54
+
55
+ def __init__(self, default_factory=_defaultdict_factory):
56
+ super().__init__(default_factory)
57
+
58
+ def __missing__(self, key):
59
+ # call the factory with a key and save the result
60
+ result = self.default_factory(key) # type: ignore[call-arg, misc]
61
+ self[key] = result
62
+ return result
@@ -1,46 +0,0 @@
1
- # Python Utilities Library
2
-
3
- Version 2.4.2, 2018 - 2026, Dmitrii Gusev
4
- *Last update: 15.05.2026*
5
-
6
- ## Project Description
7
-
8
- Useful utilities functions for various needs for the python 3.10+. Containing 'general purpose' functions.
9
-
10
- ## Versions history
11
-
12
- ### 2.4.0/2.4.1/2.4.2
13
-
14
- - many refactorings and minor code improvements
15
- - overall tests coverage now > 50%, working on improvements :)
16
- - added new date/time function, several decorators
17
- - added several useful string functions
18
- - added LoggingManager component for loguru simple configuration
19
- - v.2.4.1/v.2.4.2 - minor docs fixes
20
-
21
- ### 2.3.0
22
-
23
- Intermediate version with improvements/refactorings.
24
-
25
- ### 2.2.0
26
-
27
- Added several new functions - see sources.
28
-
29
- ### 2.1.2
30
-
31
- Major release with complete set of useful 'general purpose' functions. Documentation 'is coming'...
32
-
33
- **Warning! Versions 2.1.0, 2.1.1 are intended only for the python version = 3.10 and can be installed only for it!**
34
-
35
- ### Versions before 2.x.x
36
-
37
- **It is strongly recommended: don't use versions prior to the 2.x.x!**
38
-
39
- Main properties of the previous library versions:
40
-
41
- - set of the 'minor' and 'experimental' releases
42
- - various set of functions without consistency
43
- - many 'experimental' functions without proper testing
44
- - a lot of unnecessary code
45
- - experiments with building/dependencies management tools - no tool, pipenv poetry
46
- - unstable list of dependencies with obsolete versions
@@ -1,78 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
- """
4
- Useful date/time utilities and functions.
5
-
6
- Created: Dmitrii Gusev, 22.03.2026
7
- Modified: Dmitrii Gusev, 10.05.2026
8
- """
9
-
10
- from datetime import datetime, timedelta, timezone
11
-
12
- import pendulum
13
- from pendulum import Date
14
-
15
- from pyutilities.defaults import MSG_MODULE_ISNT_RUNNABLE
16
-
17
- MSK_TIMEZONE: timezone = timezone(timedelta(hours=3), name="Moscow Timezone (Russia)")
18
- MSK_TIMEZONE_NAME: str = "Europe/Moscow"
19
-
20
-
21
- def get_timestamp(
22
- current_timezone: timezone = MSK_TIMEZONE,
23
- days: float = 0,
24
- hours: float = 0,
25
- minutes: float = 0,
26
- seconds: float = 0,
27
- ) -> datetime:
28
- """Return timestamp: now (in the default timezone) +/- the specified time delta in hours / minutes /
29
- seconds. Default timezone can be changed by the function argument."""
30
-
31
- return datetime.now(current_timezone) + timedelta(
32
- days=days, hours=hours, minutes=minutes, seconds=seconds
33
- )
34
-
35
-
36
- def get_dates_range_before_date(date: datetime) -> tuple[int, int]:
37
- """Generates two dates range - date_from/date_to for the time period 'before today' - from the 1st day
38
- of the current month till the today - 1 day (current month). In case today is 1st day - range for the
39
- whole previous month, if today is 01.01.XXXX - range for 01.12.XXXX-1 - 31.12.XXXX-1.
40
- """
41
-
42
- # - local variables
43
- local_today: Date = Date(date.year, date.month, date.day)
44
- date_from: Date
45
- date_to: Date
46
-
47
- # - processing and calculating dates
48
- if local_today.day == 1: # today - 1st day of month, we need report for the previous month
49
-
50
- if local_today.month == 1: # we are at 01.01.XXXX - we need report for Dec.XXXX - 1
51
-
52
- date_from = pendulum.date(local_today.year - 1, 12, 1) # from: 01 Dec Year-1
53
- date_to = pendulum.date(local_today.year - 1, 12, 31) # to: 31 Dec Year-1
54
-
55
- else: # we are at 01.XX.XXXX - we need report for previous month
56
-
57
- # from: 01 Month-1 Year
58
- date_from = pendulum.date(local_today.year, local_today.month - 1, 1)
59
- # to: Last Day Month-1 Year
60
- date_to = pendulum.date(
61
- local_today.year, local_today.month - 1, local_today.subtract(months=1).days_in_month
62
- )
63
-
64
- else: # today isn't the 1st, we need report from 1st till yesterday
65
-
66
- date_from = pendulum.date(local_today.year, local_today.month, 1) # from: 01 Month Year
67
- date_to = pendulum.date(local_today.year, local_today.month, date.day - 1) # to: Day-1 Month Year
68
-
69
- # - generate from/to timestamps
70
- tstamp_from = pendulum.datetime(date_from.year, date_from.month, date_from.day)
71
- tstamp_to = pendulum.datetime(date_to.year, date_to.month, date_to.day)
72
-
73
- # - return the tuple of values
74
- return (tstamp_from.int_timestamp, tstamp_to.int_timestamp)
75
-
76
-
77
- if __name__ == "__main__":
78
- print(MSG_MODULE_ISNT_RUNNABLE)
File without changes