somepytools 1.2.2__tar.gz → 1.4.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.
- {somepytools-1.2.2 → somepytools-1.4.0}/PKG-INFO +13 -12
- {somepytools-1.2.2 → somepytools-1.4.0}/pyproject.toml +4 -4
- somepytools-1.4.0/somepytools/__init__.py +1 -0
- somepytools-1.4.0/somepytools/colab_tools.py +136 -0
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/general.py +26 -1
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/image.py +3 -1
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/typing.py +0 -1
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/video.py +3 -2
- somepytools-1.2.2/setup.py +0 -35
- somepytools-1.2.2/somepytools/__init__.py +0 -1
- {somepytools-1.2.2 → somepytools-1.4.0}/LICENSE +0 -0
- {somepytools-1.2.2 → somepytools-1.4.0}/README.md +0 -0
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/constants.py +0 -0
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/io.py +0 -0
- {somepytools-1.2.2 → somepytools-1.4.0}/somepytools/torch.py +0 -0
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: somepytools
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Just some useful Python tools
|
|
5
|
-
Home-page: https://github.com/v-goncharenko/somepytools
|
|
6
5
|
License: Apache-2.0
|
|
7
6
|
Keywords: tools,utilities,python,torch,opencv
|
|
8
7
|
Author: Vladilav Goncharenko
|
|
9
8
|
Author-email: vladislav.goncharenko@phystech.edu
|
|
10
9
|
Maintainer: Vladislav Goncharenko
|
|
11
10
|
Maintainer-email: vladislav.goncharenko@phystech.edu
|
|
12
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.9
|
|
13
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
13
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
19
|
Provides-Extra: all
|
|
19
|
-
Requires-Dist: PyYAML (>=6.0,<7.0); extra == "all"
|
|
20
|
-
Requires-Dist: matplotlib (>=3.5.1,<4.0.0); extra == "all"
|
|
21
|
-
Requires-Dist: numpy (>=1.22.3,<2.0.0); extra == "all"
|
|
22
|
-
Requires-Dist: opencv-python-headless (>=4.5.5,<5.0.0); extra == "all"
|
|
23
|
-
Requires-Dist: toml (>=0.10.2,<0.11.0); extra == "all"
|
|
24
|
-
Requires-Dist: torch (>=1.11.0,<2.0.0); extra == "all"
|
|
20
|
+
Requires-Dist: PyYAML (>=6.0,<7.0) ; extra == "all"
|
|
21
|
+
Requires-Dist: matplotlib (>=3.5.1,<4.0.0) ; extra == "all"
|
|
22
|
+
Requires-Dist: numpy (>=1.22.3,<2.0.0) ; extra == "all"
|
|
23
|
+
Requires-Dist: opencv-python-headless (>=4.5.5,<5.0.0) ; extra == "all"
|
|
24
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0) ; extra == "all"
|
|
25
|
+
Requires-Dist: torch (>=1.11.0,<2.0.0) ; extra == "all"
|
|
25
26
|
Project-URL: Repository, https://github.com/v-goncharenko/somepytools
|
|
26
27
|
Description-Content-Type: text/markdown
|
|
27
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "somepytools"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.4.0"
|
|
4
4
|
description = "Just some useful Python tools"
|
|
5
5
|
authors = ["Vladilav Goncharenko <vladislav.goncharenko@phystech.edu>"]
|
|
6
6
|
maintainers = ["Vladislav Goncharenko <vladislav.goncharenko@phystech.edu>"]
|
|
@@ -10,7 +10,7 @@ keywords = ["tools", "utilities", "python", "torch", "opencv"]
|
|
|
10
10
|
license = "Apache-2.0"
|
|
11
11
|
|
|
12
12
|
[tool.poetry.dependencies]
|
|
13
|
-
python = ">=3.
|
|
13
|
+
python = ">=3.9"
|
|
14
14
|
|
|
15
15
|
PyYAML = {version = "^6.0", optional = true}
|
|
16
16
|
toml = {version = "^0.10.2", optional = true}
|
|
@@ -23,8 +23,8 @@ matplotlib = {version = "^3.5.1", optional = true}
|
|
|
23
23
|
[tool.poetry.extras]
|
|
24
24
|
all = ["PyYAML", "toml", "numpy", "opencv-python-headless", "torch", "matplotlib"]
|
|
25
25
|
|
|
26
|
-
[tool.poetry.dev
|
|
27
|
-
pre-commit = "^
|
|
26
|
+
[tool.poetry.group.dev.dependencies]
|
|
27
|
+
pre-commit = "^4.3.0"
|
|
28
28
|
pytest = "^6.2.5"
|
|
29
29
|
|
|
30
30
|
[tool.black]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.0"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# duplicates in sheets formula: =COUNTIF(A:A, A1) > 1
|
|
2
|
+
|
|
3
|
+
from typing import Any, Union
|
|
4
|
+
|
|
5
|
+
import gspread
|
|
6
|
+
import polars as pl
|
|
7
|
+
from google.auth import default
|
|
8
|
+
from google.colab import auth
|
|
9
|
+
from oauth2client.client import GoogleCredentials
|
|
10
|
+
from pydrive2.auth import GoogleAuth
|
|
11
|
+
from pydrive2.drive import GoogleDrive
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def auth_gspread() -> gspread.client.Client:
|
|
15
|
+
auth.authenticate_user()
|
|
16
|
+
creds, _ = default()
|
|
17
|
+
gc = gspread.authorize(creds)
|
|
18
|
+
return gc
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def auth_pydrive(dummy_call: bool = False) -> GoogleDrive:
|
|
22
|
+
"""
|
|
23
|
+
Args:
|
|
24
|
+
dummy_call: needed if you want to perform non PyDrive2 native operations with service object
|
|
25
|
+
"""
|
|
26
|
+
auth.authenticate_user()
|
|
27
|
+
gauth = GoogleAuth()
|
|
28
|
+
gauth.credentials = GoogleCredentials.get_application_default()
|
|
29
|
+
drive = GoogleDrive(gauth)
|
|
30
|
+
|
|
31
|
+
if dummy_call:
|
|
32
|
+
file_list = drive.ListFile( # noqa: F841
|
|
33
|
+
{"q": "'root' in parents and trashed=false"}
|
|
34
|
+
).GetList()
|
|
35
|
+
|
|
36
|
+
return drive
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def sheets(gc, spreadsheet_id: str) -> dict[str, Any]:
|
|
40
|
+
""""""
|
|
41
|
+
spreadsheet = gc.open_by_key(spreadsheet_id)
|
|
42
|
+
return {ws.title: ws for ws in spreadsheet}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def worksheet2pl(worksheet):
|
|
46
|
+
all_vals = worksheet.get(
|
|
47
|
+
major_dimension=gspread.utils.Dimension.cols,
|
|
48
|
+
value_render_option=gspread.utils.ValueRenderOption.unformatted,
|
|
49
|
+
date_time_render_option=gspread.utils.DateTimeOption.formatted_string,
|
|
50
|
+
pad_values=True,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
df = pl.DataFrame(all_vals, strict=False)
|
|
54
|
+
df = df.rename(df.head(1).to_dicts().pop())
|
|
55
|
+
df = df.with_row_index()
|
|
56
|
+
df = df.filter(pl.col("index") != 0)
|
|
57
|
+
return df
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def number2letters(q: int) -> str:
|
|
61
|
+
"""Helper function to convert number of column to its index, like 10 -> 'A'"""
|
|
62
|
+
q = q - 1
|
|
63
|
+
result = ""
|
|
64
|
+
|
|
65
|
+
while q >= 0:
|
|
66
|
+
remain = q % 26
|
|
67
|
+
result = chr(remain + 65) + result
|
|
68
|
+
q = q // 26 - 1
|
|
69
|
+
|
|
70
|
+
return result
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def colrow2range(col: int, row: int) -> str:
|
|
74
|
+
"""Helper function converting coordinates into sheets range string representation"""
|
|
75
|
+
return number2letters(col) + str(row)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def write_table(
|
|
79
|
+
ws,
|
|
80
|
+
table: Union[list, pl.DataFrame],
|
|
81
|
+
left: int = 1,
|
|
82
|
+
top: int = 1,
|
|
83
|
+
*,
|
|
84
|
+
with_headers: bool = True,
|
|
85
|
+
):
|
|
86
|
+
"""Updates the google spreadsheet with given table
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
ws: gspread.models.Worksheet object
|
|
90
|
+
rows: a table (list of lists) or polars data frame (will be converted internally)
|
|
91
|
+
left: the number of the first column in the target document (beginning with 1)
|
|
92
|
+
top: the number of first row in the target document (beginning with 1)
|
|
93
|
+
with_headers: in case of rows as pl.DataFrame to take headers or not
|
|
94
|
+
"""
|
|
95
|
+
if isinstance(table, pl.DataFrame):
|
|
96
|
+
columns = table.columns
|
|
97
|
+
table = table.rows()
|
|
98
|
+
if with_headers:
|
|
99
|
+
table.insert(0, columns)
|
|
100
|
+
|
|
101
|
+
# number of rows and columns
|
|
102
|
+
num_lines, num_columns = len(table), len(table[0])
|
|
103
|
+
|
|
104
|
+
# selection of the range that will be updated
|
|
105
|
+
top_left = colrow2range(left, top)
|
|
106
|
+
bot_right = colrow2range(left + num_columns - 1, top + num_lines - 1)
|
|
107
|
+
cell_list = ws.range(f"{top_left}:{bot_right}")
|
|
108
|
+
|
|
109
|
+
# modifying the values in the range
|
|
110
|
+
|
|
111
|
+
for cell in cell_list:
|
|
112
|
+
cell.value = table[cell.row - top][cell.col - left]
|
|
113
|
+
|
|
114
|
+
# update in batch
|
|
115
|
+
ws.update_cells(cell_list)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def copy_drive_file(drive, source: str, dest_dir: str, dest_fname: str):
|
|
119
|
+
"""Copy Google Drive file
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
source: id of the file to be copyed
|
|
123
|
+
dest_dir: id of directory to put copy to
|
|
124
|
+
dest_fname: name of restulting document
|
|
125
|
+
"""
|
|
126
|
+
return (
|
|
127
|
+
drive.auth.service.files()
|
|
128
|
+
.copy(
|
|
129
|
+
fileId=source,
|
|
130
|
+
body={
|
|
131
|
+
"parents": [{"kind": "drive#fileLink", "id": dest_dir}],
|
|
132
|
+
"title": dest_fname,
|
|
133
|
+
},
|
|
134
|
+
)
|
|
135
|
+
.execute()
|
|
136
|
+
)
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import shutil
|
|
2
|
+
from datetime import date, datetime, timedelta
|
|
2
3
|
from functools import wraps
|
|
3
4
|
from inspect import getfullargspec
|
|
4
5
|
from pathlib import Path
|
|
6
|
+
from typing import Any, Iterator, Union, get_args
|
|
5
7
|
from urllib.parse import urlparse
|
|
6
8
|
from urllib.request import urlopen
|
|
7
9
|
from zipfile import ZipFile
|
|
8
10
|
|
|
9
11
|
from .constants import SIZE_CONSTANTS
|
|
10
|
-
from .typing import
|
|
12
|
+
from .typing import Directory, File
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def str2pathlib(func):
|
|
@@ -160,3 +162,26 @@ def dir_size(
|
|
|
160
162
|
src = f.resolve()
|
|
161
163
|
total_size += dir_size(src, units)
|
|
162
164
|
return total_size
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def daterange(
|
|
168
|
+
start_date: Union[str, datetime],
|
|
169
|
+
end_date: Union[str, datetime],
|
|
170
|
+
*,
|
|
171
|
+
include_last: bool = False,
|
|
172
|
+
) -> Iterator[date]:
|
|
173
|
+
"""Generates dates in requested range
|
|
174
|
+
|
|
175
|
+
Note:
|
|
176
|
+
Date format is ISO: 'yyyy-mm-dd'
|
|
177
|
+
"""
|
|
178
|
+
if isinstance(start_date, str):
|
|
179
|
+
start_date = datetime.strptime(start_date, "%Y-%m-%d").date()
|
|
180
|
+
if isinstance(end_date, str):
|
|
181
|
+
end_date = datetime.strptime(end_date, "%Y-%m-%d").date()
|
|
182
|
+
days = (end_date - start_date).days
|
|
183
|
+
if include_last:
|
|
184
|
+
days += 1
|
|
185
|
+
|
|
186
|
+
for i in range(days):
|
|
187
|
+
yield start_date + timedelta(i)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from contextlib import contextmanager
|
|
2
2
|
from pathlib import Path
|
|
3
|
+
from typing import Iterable, Sequence, Union
|
|
3
4
|
|
|
4
5
|
from .general import str2pathlib
|
|
5
|
-
from .typing import Array, File
|
|
6
|
+
from .typing import Array, File
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
try:
|
|
@@ -41,7 +42,7 @@ def open_video(video_path: File, mode: str = "r", *args):
|
|
|
41
42
|
elif mode == "w":
|
|
42
43
|
video = cv2.VideoWriter(video_path.as_posix(), *args)
|
|
43
44
|
else:
|
|
44
|
-
raise ValueError(f'Incorrect open mode
|
|
45
|
+
raise ValueError(f'Incorrect open mode {mode!r}; "r" or "w" expected!')
|
|
45
46
|
|
|
46
47
|
if not video.isOpened():
|
|
47
48
|
raise ValueError(f"Video {video_path} is not opened!")
|
somepytools-1.2.2/setup.py
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
packages = \
|
|
5
|
-
['somepytools']
|
|
6
|
-
|
|
7
|
-
package_data = \
|
|
8
|
-
{'': ['*']}
|
|
9
|
-
|
|
10
|
-
extras_require = \
|
|
11
|
-
{'all': ['PyYAML>=6.0,<7.0',
|
|
12
|
-
'toml>=0.10.2,<0.11.0',
|
|
13
|
-
'numpy>=1.22.3,<2.0.0',
|
|
14
|
-
'opencv-python-headless>=4.5.5,<5.0.0',
|
|
15
|
-
'torch>=1.11.0,<2.0.0',
|
|
16
|
-
'matplotlib>=3.5.1,<4.0.0']}
|
|
17
|
-
|
|
18
|
-
setup_kwargs = {
|
|
19
|
-
'name': 'somepytools',
|
|
20
|
-
'version': '1.2.2',
|
|
21
|
-
'description': 'Just some useful Python tools',
|
|
22
|
-
'long_description': "# Some useful tools for Python [in context of Data Science]\n\n[](https://pypi.org/project/somepytools/)\n[](https://pepy.tech/project/somepytools)\n[](https://github.com/v-goncharenko/somepytools/blob/master/LICENSE)\n[](https://github.com/psf/black)\n\nHere I gather functions that are handful in Data Science & Machine Learning\nprojects.\n\nAll functions are described by their docstrings, rendering documentation is next\nstep.\n\n## Installation\n\nIt's [published on PyPI](https://pypi.org/project/somepytools/), so simply\n\n`pip install somepytools`\n\n## Reference\n\nModules inclues:\n\n- extended typing module\n- common read-write operations for configs\n- utils to work with filesystem\n- functions to handle videos in opencv\n- torch utilities (infer and count parameters)\n- even more (e.g. wrapper to convert strings inputs to `pathlib`)\n\nFor now it's better to go through the files and look at contents\n",
|
|
23
|
-
'author': 'Vladilav Goncharenko',
|
|
24
|
-
'author_email': 'vladislav.goncharenko@phystech.edu',
|
|
25
|
-
'maintainer': 'Vladislav Goncharenko',
|
|
26
|
-
'maintainer_email': 'vladislav.goncharenko@phystech.edu',
|
|
27
|
-
'url': 'https://github.com/v-goncharenko/somepytools',
|
|
28
|
-
'packages': packages,
|
|
29
|
-
'package_data': package_data,
|
|
30
|
-
'extras_require': extras_require,
|
|
31
|
-
'python_requires': '>=3.8',
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
setup(**setup_kwargs)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.2.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|