tracktolib 0.61.2__tar.gz → 0.62.1__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.
@@ -1,19 +1,23 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracktolib
3
- Version: 0.61.2
3
+ Version: 0.62.1
4
4
  Summary: Utility library for python
5
- License: MIT
6
- License-File: LICENSE
7
5
  Keywords: utility
8
- Author: Julien Brayere
9
6
  Author-email: julien.brayere@tracktor.fr
10
- Requires-Python: >=3.12,<4.0
11
- Classifier: License :: OSI Approved :: MIT License
7
+ License-Expression: MIT
12
8
  Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Classifier: Programming Language :: Python :: 3.14
9
+ Requires-Dist: fastapi>=0.103.2 ; extra == 'api'
10
+ Requires-Dist: pydantic>=2 ; extra == 'api'
11
+ Requires-Dist: httpx>=0.25.0 ; extra == 'http'
12
+ Requires-Dist: python-json-logger>=3.2.1 ; extra == 'logs'
13
+ Requires-Dist: asyncpg>=0.27.0 ; extra == 'pg'
14
+ Requires-Dist: rich>=13.6.0 ; extra == 'pg'
15
+ Requires-Dist: psycopg>=3.1.12 ; extra == 'pg-sync'
16
+ Requires-Dist: aiobotocore>=2.9.0 ; extra == 's3'
17
+ Requires-Dist: minio>=7.2.0 ; extra == 's3-minio'
18
+ Requires-Dist: pycryptodome>=3.20.0 ; extra == 's3-minio'
19
+ Requires-Dist: deepdiff>=8.1.0 ; extra == 'tests'
20
+ Requires-Python: >=3.12, <4.0
17
21
  Provides-Extra: api
18
22
  Provides-Extra: http
19
23
  Provides-Extra: logs
@@ -22,19 +26,6 @@ Provides-Extra: pg-sync
22
26
  Provides-Extra: s3
23
27
  Provides-Extra: s3-minio
24
28
  Provides-Extra: tests
25
- Requires-Dist: aiobotocore (>=2.9.0) ; extra == "s3"
26
- Requires-Dist: asyncpg (>=0.27.0) ; extra == "pg"
27
- Requires-Dist: deepdiff (>=8.1.0) ; extra == "tests"
28
- Requires-Dist: fastapi (>=0.103.2) ; extra == "api"
29
- Requires-Dist: httpx (>=0.25.0) ; extra == "http"
30
- Requires-Dist: minio (>=7.2.0) ; extra == "s3-minio"
31
- Requires-Dist: psycopg (>=3.1.12) ; extra == "pg-sync"
32
- Requires-Dist: pycryptodome (>=3.20.0) ; extra == "s3-minio"
33
- Requires-Dist: pydantic (>=2) ; extra == "api"
34
- Requires-Dist: python-json-logger (>=3.2.1) ; extra == "logs"
35
- Requires-Dist: rich (>=13.6.0) ; extra == "pg"
36
- Project-URL: Homepage, https://github.com/tracktor/tracktolib
37
- Project-URL: Repository, https://github.com/tracktor/tracktolib
38
29
  Description-Content-Type: text/markdown
39
30
 
40
31
  # Tracktolib
@@ -47,15 +38,12 @@ Utility library for python
47
38
 
48
39
  # Installation
49
40
 
50
- You can choose to not install all the dependencies by specifying
51
- the [extra](https://python-poetry.org/docs/cli/#options-4) parameter such as:
41
+ Just run:
52
42
 
53
43
  ```bash
54
- poetry add tracktolib@latest -E pg-sync -E tests --group dev
44
+ uv add tracktolib@latest
55
45
  ```
56
46
 
57
- Here we only install the utilities using `psycopg` (pg-sync) and `deepdiff` (tests) for the dev environment.
58
-
59
47
  # Utilities
60
48
 
61
49
  - **log**
@@ -123,4 +111,3 @@ Utility functions using [httpx](https://www.python-httpx.org/)
123
111
  - **api**
124
112
 
125
113
  Utility functions using [fastapi](https://fastapi.tiangolo.com/)
126
-
@@ -8,15 +8,12 @@ Utility library for python
8
8
 
9
9
  # Installation
10
10
 
11
- You can choose to not install all the dependencies by specifying
12
- the [extra](https://python-poetry.org/docs/cli/#options-4) parameter such as:
11
+ Just run:
13
12
 
14
13
  ```bash
15
- poetry add tracktolib@latest -E pg-sync -E tests --group dev
14
+ uv add tracktolib@latest
16
15
  ```
17
16
 
18
- Here we only install the utilities using `psycopg` (pg-sync) and `deepdiff` (tests) for the dev environment.
19
-
20
17
  # Utilities
21
18
 
22
19
  - **log**
@@ -0,0 +1,123 @@
1
+ [project]
2
+ name = "tracktolib"
3
+ version = "0.62.1"
4
+ authors = [
5
+ { email = "julien.brayere@tracktor.fr" }
6
+ ]
7
+ description = "Utility library for python"
8
+ license = "MIT"
9
+ readme = "README.md"
10
+ homepage = "https://github.com/tracktor/tracktolib"
11
+ repository = "https://github.com/tracktor/tracktolib"
12
+ keywords = ["utility"]
13
+ classifiers = [
14
+ "Operating System :: OS Independent"
15
+ ]
16
+ include = [
17
+ "LICENSE"
18
+ ]
19
+ requires-python = ">=3.12,<4.0"
20
+
21
+ dependencies = []
22
+
23
+ [project.optional-dependencies]
24
+ logs = ["python-json-logger>=3.2.1"]
25
+ pg-sync = ["psycopg>=3.1.12"]
26
+ s3-minio = [
27
+ "minio>=7.2.0",
28
+ # Needed for minio, otherwise it raises ModuleNotFoundError: No module named 'Crypto.Cipher'
29
+ "pycryptodome>=3.20.0",
30
+ ]
31
+ s3 = ["aiobotocore>=2.9.0"]
32
+ tests = ["deepdiff>=8.1.0"]
33
+ http = ["httpx>=0.25.0"]
34
+ api = [
35
+ "fastapi>=0.103.2",
36
+ "pydantic>=2",
37
+ ]
38
+ pg = [
39
+ "asyncpg>=0.27.0",
40
+ "rich>=13.6.0",
41
+ ]
42
+
43
+ [dependency-groups]
44
+ dev = [
45
+ "pytest-cov>=7.0.0,<8",
46
+ "pytest>=9.0.1,<10",
47
+ "pyright>=1.1.371",
48
+ "ruff>=0.14.5",
49
+ "pydantic>=2.12.4",
50
+ # Issue for mac with trackit version of multidict
51
+ "multidict>=6.0.5",
52
+ "fastapi>=0.111.1",
53
+ "httpx>=0.27.0",
54
+ "psycopg>=3.2.1",
55
+ "minio>=7.2.7",
56
+ "pycryptodome>=3.23.0",
57
+ "aiobotocore==2.15.2",
58
+ "python-json-logger>=3.2.0",
59
+ "pre-commit>=4.4.0",
60
+ ]
61
+
62
+ bump = [
63
+ "commitizen>=4.10.0"
64
+ ]
65
+
66
+ [build-system]
67
+ requires = ["uv_build>=0.9.4,<0.10.0"]
68
+ build-backend = "uv_build"
69
+
70
+ [tool.uv.build-backend]
71
+ module-name = "tracktolib"
72
+ module-root = ""
73
+
74
+ [tool.pytest.ini_options]
75
+ addopts = "--cov=tracktolib -s -q -x --no-cov-on-fail"
76
+ testpaths = [
77
+ "tests"
78
+ ]
79
+ python_files = "*.py"
80
+ filterwarnings = [
81
+ "ignore::DeprecationWarning",
82
+ "ignore::PendingDeprecationWarning"
83
+ ]
84
+
85
+ [tool.pyright]
86
+ include = ["tracktolib", "tests"]
87
+ exclude = []
88
+
89
+ pythonVersion = "3.13"
90
+ pythonPlatform = "Linux"
91
+
92
+ [tool.commitizen]
93
+ name = "cz_conventional_commits"
94
+ version = "0.62.1"
95
+ tag_format = "$version"
96
+ version_files = [
97
+ "pyproject.toml:version"
98
+ ]
99
+ bump_message = "release $current_version → $new_version [skip ci]"
100
+
101
+
102
+ [tool.ruff]
103
+ line-length = 120
104
+ target-version = "py313"
105
+
106
+
107
+ [tool.ruff.lint.per-file-ignores]
108
+ "__init__.py" = [
109
+ # imported but unused
110
+ "F401",
111
+ # unable to detect undefined names
112
+ "F403",
113
+ #
114
+ "F405"
115
+ ]
116
+
117
+ [tool.ruff.lint.flake8-quotes]
118
+ docstring-quotes = "double"
119
+ inline-quotes = "single"
120
+
121
+ [tool.ruff.lint.flake8-tidy-imports]
122
+ # Disallow all relative imports.
123
+ ban-relative-imports = "all"
@@ -0,0 +1,8 @@
1
+ from importlib import metadata
2
+
3
+ try:
4
+ __version__ = metadata.version("padmy")
5
+ except metadata.PackageNotFoundError:
6
+ __version__ = "0.0.0"
7
+
8
+ __all__ = ("__version__",)
@@ -1,6 +1,6 @@
1
1
  import logging
2
- from typing import Literal, overload, Any, TypeGuard
3
2
  from dataclasses import dataclass
3
+ from typing import Literal, overload, Any, TypeGuard
4
4
 
5
5
  try:
6
6
  from pythonjsonlogger.json import JsonFormatter
@@ -18,12 +18,12 @@ class CustomJsonFormatter(JsonFormatter):
18
18
  self.version: str = version
19
19
  super().__init__(*args, **kwargs)
20
20
 
21
- def add_fields(self, log_record: dict[str, Any], record: logging.LogRecord, message_dict: dict[str, Any]):
22
- super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)
21
+ def add_fields(self, log_data: dict[str, Any], record: logging.LogRecord, message_dict: dict[str, Any]):
22
+ super(CustomJsonFormatter, self).add_fields(log_data, record, message_dict)
23
23
 
24
- log_record.pop("color_message", None)
25
- if not log_record.get("version"):
26
- log_record["version"] = self.version
24
+ log_data.pop("color_message", None)
25
+ if not log_data.get("version"):
26
+ log_data["version"] = self.version
27
27
 
28
28
 
29
29
  @overload
@@ -217,7 +217,7 @@ def get_update_fields(
217
217
  fields.append(
218
218
  f"{_col} = ${_counter}"
219
219
  if k not in _merge_keys
220
- else f"{_col} = COALESCE(t.{_col}, JSONB_BUILD_OBJECT()) || " f"${_counter}"
220
+ else f"{_col} = COALESCE(t.{_col}, JSONB_BUILD_OBJECT()) || ${_counter}"
221
221
  )
222
222
  counter += 1
223
223
  return ",\n".join(fields), values + where_values
@@ -225,10 +225,14 @@ def get_update_fields(
225
225
 
226
226
  @dataclass
227
227
  class PGUpdateQuery(PGQuery):
228
- """Value to start the arguments from:
229
- For instance, with a value of 10, the first argument will be $11
228
+ """
229
+ Postgresql UPDATE query generator
230
230
  """
231
231
 
232
+ """
233
+ Value to start the arguments from:
234
+ For instance, with a value of 10, the first argument will be $11
235
+ """
232
236
  start_from: int | None = None
233
237
  """Keys to use for the WHERE clause. Theses fields will not be updated"""
234
238
  where_keys: list[str] | None = None
@@ -239,6 +243,8 @@ class PGUpdateQuery(PGQuery):
239
243
  return_keys: bool = False
240
244
  """Values to update using merge (like {}::jsonb || {}::jsonb)"""
241
245
  merge_keys: list[str] | None = None
246
+ """If True, the query is for many items and values will be a list of tuples"""
247
+ is_many: bool = False
242
248
 
243
249
  _update_fields: str | None = field(init=False, default=None)
244
250
  _values: list | None = field(init=False, default=None)
@@ -264,7 +270,7 @@ class PGUpdateQuery(PGQuery):
264
270
  def values(self):
265
271
  if not self._values:
266
272
  raise ValueError("No values found")
267
- if len(self.items) == 1:
273
+ if len(self.items) == 1 and not self.is_many:
268
274
  return self._values
269
275
  _where_keys = self.where_keys or []
270
276
  _keys_not_where = [k for k in self.keys if k not in _where_keys]
@@ -516,7 +522,13 @@ async def update_many(
516
522
  query_callback: QueryCallback[PGUpdateQuery] | None = None,
517
523
  ):
518
524
  query = PGUpdateQuery(
519
- table=table, items=items, start_from=start_from, where_keys=keys, where=where, merge_keys=merge_keys
525
+ table=table,
526
+ items=items,
527
+ start_from=start_from,
528
+ where_keys=keys,
529
+ where=where,
530
+ merge_keys=merge_keys,
531
+ is_many=True,
520
532
  )
521
533
  if query_callback is not None:
522
534
  query_callback(query)
@@ -130,7 +130,7 @@ async def upsert_csv(
130
130
 
131
131
  missing_cols = set(_columns) - set(infos.keys())
132
132
  if missing_cols:
133
- raise ValueError(f'Could not find the following columns in the table: {",".join(missing_cols)}')
133
+ raise ValueError(f"Could not find the following columns in the table: {','.join(missing_cols)}")
134
134
 
135
135
  async with conn.transaction():
136
136
  _tmp_table, _tmp_query, _insert_query = get_tmp_table_query(
tracktolib-0.61.2/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2018 Julien Brayere
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
@@ -1,116 +0,0 @@
1
- [tool.poetry]
2
- name = "tracktolib"
3
- version = "0.61.2"
4
- description = "Utility library for python"
5
- authors = ["Julien Brayere <julien.brayere@tracktor.fr>"]
6
- license = "MIT"
7
- readme = "README.md"
8
- homepage = "https://github.com/tracktor/tracktolib"
9
- repository = "https://github.com/tracktor/tracktolib"
10
- keywords = ["utility"]
11
- classifiers = [
12
- "Operating System :: OS Independent"
13
- ]
14
- include = [
15
- "LICENSE"
16
- ]
17
-
18
- [tool.poetry.dependencies]
19
- python = ">=3.12,<4.0"
20
-
21
- python-json-logger = { version = ">=3.2.1", optional = true }
22
- psycopg = { version = ">=3.1.12", optional = true }
23
- minio = { version = ">=7.2.0", optional = true }
24
- # Needed for minio, otherwise it raises ModuleNotFoundError: No module named 'Crypto.Cipher'
25
- pycryptodome = { version = ">=3.20.0", optional = true }
26
- aiobotocore = { version = ">=2.9.0", optional = true }
27
- deepdiff = { version = ">=8.1.0", optional = true }
28
- httpx = { version = ">=0.25.0", optional = true }
29
- fastapi = { version = ">=0.103.2", optional = true }
30
- pydantic = { version = ">=2", optional = true }
31
- asyncpg = ">=0.27.0"
32
- rich = { version = ">=13.6.0", optional = true }
33
-
34
- [tool.poetry.extras]
35
- logs = ["python-json-logger"]
36
- pg-sync = ["psycopg"]
37
- s3-minio = ["minio", "pycryptodome"]
38
- s3 = ["aiobotocore"]
39
- tests = ["deepdiff"]
40
- http = ["httpx"]
41
- api = ["fastapi", "pydantic"]
42
- pg = ["asyncpg", "rich"]
43
-
44
- [tool.poetry.group.dev.dependencies]
45
- commitizen = "^3.11.0"
46
- pytest-cov = "^5.0.0"
47
- pytest = "^8.2.2"
48
- pyright = "^1.1.371"
49
- ruff = "^0.5.2"
50
- pydantic = "^2.8.2"
51
- # Issue for mac with trackit version of multidict
52
- multidict = "^6.0.5"
53
- fastapi ="^0.111.1"
54
- httpx = "^0.27.0"
55
- psycopg = "^3.2.1"
56
- minio = "^7.2.7"
57
- pycryptodome = "^3.20.0"
58
- aiobotocore = "2.15.2"
59
- python-json-logger = "^3.2.0"
60
-
61
-
62
- [build-system]
63
- requires = ["poetry-core"]
64
- build-backend = "poetry.core.masonry.api"
65
-
66
- [tool.pytest.ini_options]
67
- addopts = "--cov=tracktolib -s -q -x --no-cov-on-fail"
68
- testpaths = [
69
- "tests"
70
- ]
71
- python_files = "*.py"
72
- filterwarnings = [
73
- "ignore::DeprecationWarning",
74
- "ignore::PendingDeprecationWarning"
75
- ]
76
-
77
- [tool.pyright]
78
- include = ["tracktolib", "tests"]
79
- exclude = []
80
-
81
- pythonVersion = "3.12"
82
- pythonPlatform = "Linux"
83
-
84
- [tool.commitizen]
85
- name = "cz_conventional_commits"
86
- version = "0.61.2"
87
- tag_format = "$version"
88
- version_files = [
89
- "pyproject.toml:version"
90
- ]
91
- bump_message = "release $current_version → $new_version [skip ci]"
92
-
93
-
94
- [tool.ruff]
95
- line-length = 120
96
- target-version = "py312"
97
- # Waiting for fix: https://github.com/charliermarsh/ruff/issues/282
98
- #ignore = ["E999"]
99
-
100
- [tool.ruff.lint.per-file-ignores]
101
- "__init__.py" = [
102
- # imported but unused
103
- "F401",
104
- # unable to detect undefined names
105
- "F403",
106
- #
107
- "F405"
108
- ]
109
-
110
- [tool.ruff.lint.flake8-quotes]
111
- docstring-quotes = "double"
112
- inline-quotes = "single"
113
-
114
- [tool.ruff.lint.flake8-tidy-imports]
115
- # Disallow all relative imports.
116
- ban-relative-imports = "all"
File without changes