mayutils 1.2.6__tar.gz → 1.2.8__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.
- {mayutils-1.2.6 → mayutils-1.2.8}/PKG-INFO +1 -1
- {mayutils-1.2.6 → mayutils-1.2.8}/pyproject.toml +1 -1
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/queries/__init__.py +7 -2
- mayutils-1.2.8/src/mayutils/data/read.py +86 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/memoisation.py +3 -1
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/dataframes.py +62 -1
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/datetime.py +11 -1
- mayutils-1.2.6/src/mayutils/data/read.py +0 -61
- {mayutils-1.2.6 → mayutils-1.2.8}/LICENSE +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/README.md +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/core/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/core/constants.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/analysis/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/cache/.gitkeep +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/live.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/local.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/queries/.gitkeep +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/data/queries/examples/.gitkeep +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/benchmarking.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/databases.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/filesystem.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/logging.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/oauth.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/environment/webdrivers.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/export/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/export/images.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/export/pdf.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/export/slides.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/interfaces/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/interfaces/google.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/interfaces/microsoft.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/interfaces/streamlit.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/mathematics/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/mathematics/numba.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/mathematics/numpy.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/classes.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/colours.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/decorators.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/dictionaries.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/functions.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/hashing.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/numbers.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/strings.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/objects/types.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/scripts/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/scripts/clear_cache.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/scripts/versioning.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/testing/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/console.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/combine.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/matplotlib/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/matplotlib/template.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/plotly/__init__.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/plotly/charts.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/plotly/templates.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/plotly/traces.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/graphs/plotly/utilities.py +0 -0
- {mayutils-1.2.6 → mayutils-1.2.8}/src/mayutils/visualisation/notebook.py +0 -0
|
@@ -24,7 +24,7 @@ QUERIES_FOLDERS = get_queries_folders()
|
|
|
24
24
|
|
|
25
25
|
def get_query(
|
|
26
26
|
query_name: Path | str,
|
|
27
|
-
queries_folders: tuple[Path, ...],
|
|
27
|
+
queries_folders: tuple[Path, ...] = QUERIES_FOLDERS,
|
|
28
28
|
) -> str:
|
|
29
29
|
path = Path(query_name)
|
|
30
30
|
for queries_folder in queries_folders:
|
|
@@ -33,7 +33,12 @@ def get_query(
|
|
|
33
33
|
except ValueError:
|
|
34
34
|
continue
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
try:
|
|
37
|
+
return read_file(path=path)
|
|
38
|
+
except ValueError:
|
|
39
|
+
raise ValueError(
|
|
40
|
+
f"No such query {query_name} found in the query folders {', '.join(list(map(str, queries_folders)))} or at the path {path}"
|
|
41
|
+
)
|
|
37
42
|
|
|
38
43
|
|
|
39
44
|
def get_formatted_query(
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from functools import _lru_cache_wrapper
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Literal, overload
|
|
4
|
+
|
|
5
|
+
from pandas import DataFrame
|
|
6
|
+
import polars as pl
|
|
7
|
+
|
|
8
|
+
from mayutils.data import CACHE_FOLDER
|
|
9
|
+
from mayutils.data.queries import QUERIES_FOLDERS, get_formatted_query
|
|
10
|
+
from mayutils.environment.filesystem import encode_path
|
|
11
|
+
from mayutils.environment.memoisation import DataframeBackends
|
|
12
|
+
from mayutils.objects.dataframes import DataFrames, read_parquet, to_parquet
|
|
13
|
+
from mayutils.objects.hashing import hash_inputs
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@overload
|
|
17
|
+
def get_query_data(
|
|
18
|
+
query_name: Path | str,
|
|
19
|
+
read_query: _lru_cache_wrapper[DataFrames],
|
|
20
|
+
dataframe_backend: Literal["pandas"],
|
|
21
|
+
queries_folders: tuple[Path, ...] = QUERIES_FOLDERS,
|
|
22
|
+
cache: bool | Literal["persistent"] = True,
|
|
23
|
+
**format_kwargs,
|
|
24
|
+
) -> DataFrame: ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@overload
|
|
28
|
+
def get_query_data(
|
|
29
|
+
query_name: Path | str,
|
|
30
|
+
read_query: _lru_cache_wrapper[DataFrames],
|
|
31
|
+
dataframe_backend: Literal["polars"],
|
|
32
|
+
queries_folders: tuple[Path, ...] = QUERIES_FOLDERS,
|
|
33
|
+
cache: bool | Literal["persistent"] = True,
|
|
34
|
+
**format_kwargs,
|
|
35
|
+
) -> pl.DataFrame: ...
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def get_query_data(
|
|
39
|
+
query_name: Path | str,
|
|
40
|
+
read_query: _lru_cache_wrapper[DataFrames],
|
|
41
|
+
dataframe_backend: DataframeBackends = "pandas",
|
|
42
|
+
queries_folders: tuple[Path, ...] = QUERIES_FOLDERS,
|
|
43
|
+
cache: bool | Literal["persistent"] = True,
|
|
44
|
+
**format_kwargs,
|
|
45
|
+
) -> DataFrames:
|
|
46
|
+
if (
|
|
47
|
+
cache is False
|
|
48
|
+
and hasattr(read_query, "cache_clear")
|
|
49
|
+
and callable(getattr(read_query, "cache_clear"))
|
|
50
|
+
):
|
|
51
|
+
read_query.cache_clear()
|
|
52
|
+
|
|
53
|
+
cache_name = f"{encode_path(path=query_name)}_data_{
|
|
54
|
+
hash_inputs(
|
|
55
|
+
query_name=query_name,
|
|
56
|
+
**format_kwargs,
|
|
57
|
+
)
|
|
58
|
+
}"
|
|
59
|
+
cache_file = CACHE_FOLDER / f"{cache_name}.parquet"
|
|
60
|
+
|
|
61
|
+
if cache != "persistent" or not cache_file.is_file():
|
|
62
|
+
query_string = get_formatted_query(
|
|
63
|
+
query_name=query_name,
|
|
64
|
+
queries_folders=queries_folders,
|
|
65
|
+
**format_kwargs,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
query_data = read_query(
|
|
69
|
+
query_string=query_string,
|
|
70
|
+
dataframe_backend=dataframe_backend,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if cache == "persistent":
|
|
74
|
+
to_parquet(
|
|
75
|
+
df=query_data,
|
|
76
|
+
path=cache_file,
|
|
77
|
+
index=True,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
else:
|
|
81
|
+
query_data = read_parquet(
|
|
82
|
+
path=cache_file,
|
|
83
|
+
dataframe_backend=dataframe_backend,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return query_data
|
|
@@ -15,6 +15,8 @@ from mayutils.objects.hashing import hash_inputs
|
|
|
15
15
|
|
|
16
16
|
T = TypeVar("T", bound=Callable[..., Any])
|
|
17
17
|
|
|
18
|
+
DataframeBackends = Literal["pandas", "polars"]
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
@flexwrap
|
|
20
22
|
class cache(object):
|
|
@@ -139,7 +141,7 @@ class cache_df(object):
|
|
|
139
141
|
*,
|
|
140
142
|
format: Literal["parquet", "csv", "feather", "xlsx"] = "parquet",
|
|
141
143
|
cache_folder: Path | str = CACHE_FOLDER,
|
|
142
|
-
dataframe_backend:
|
|
144
|
+
dataframe_backend: DataframeBackends = "pandas",
|
|
143
145
|
) -> None:
|
|
144
146
|
if func is None:
|
|
145
147
|
raise ValueError("No function provided")
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
-
from typing import Callable, Literal, Optional, Self
|
|
2
|
+
from typing import Callable, Literal, Optional, Self, TypeAlias, get_args
|
|
3
3
|
|
|
4
4
|
from itables import show
|
|
5
5
|
from great_tables import GT
|
|
6
|
+
import pandas as pd
|
|
6
7
|
from pandas import (
|
|
7
8
|
DataFrame,
|
|
8
9
|
ExcelWriter,
|
|
@@ -24,10 +25,14 @@ from dataframe_image._pandas_accessor import (
|
|
|
24
25
|
prepare_converter,
|
|
25
26
|
save_image,
|
|
26
27
|
)
|
|
28
|
+
import polars as pl
|
|
29
|
+
from mayutils.environment.memoisation import DataframeBackends
|
|
27
30
|
import numpy as np
|
|
28
31
|
from mayutils.objects.colours import Colour
|
|
29
32
|
from mayutils.export import OUTPUT_FOLDER
|
|
30
33
|
|
|
34
|
+
DataFrames: TypeAlias = pd.DataFrame | pl.DataFrame
|
|
35
|
+
|
|
31
36
|
DATA_FOLDER = OUTPUT_FOLDER / "Data"
|
|
32
37
|
|
|
33
38
|
|
|
@@ -524,6 +529,62 @@ class IndexUtilsAccessor(object):
|
|
|
524
529
|
# raise TypeError(f"Unsupported DataFrame type: {type(df)}")
|
|
525
530
|
|
|
526
531
|
|
|
532
|
+
def to_parquet(
|
|
533
|
+
df: DataFrames,
|
|
534
|
+
path: Path | str,
|
|
535
|
+
dataframe_backend: Optional[DataframeBackends] = None,
|
|
536
|
+
**kwargs,
|
|
537
|
+
) -> None:
|
|
538
|
+
path = Path(path)
|
|
539
|
+
|
|
540
|
+
if dataframe_backend is None:
|
|
541
|
+
module = type(df).__module__
|
|
542
|
+
|
|
543
|
+
if module not in get_args(DataframeBackends):
|
|
544
|
+
raise TypeError(f"Unsupported DataFrame type: {module}")
|
|
545
|
+
|
|
546
|
+
dataframe_backend = module # type: ignore
|
|
547
|
+
|
|
548
|
+
if dataframe_backend == "pandas":
|
|
549
|
+
assert isinstance(df, pd.DataFrame)
|
|
550
|
+
|
|
551
|
+
df.to_parquet(
|
|
552
|
+
path=path,
|
|
553
|
+
index=kwargs.pop("index", True),
|
|
554
|
+
**kwargs,
|
|
555
|
+
)
|
|
556
|
+
elif dataframe_backend == "polars":
|
|
557
|
+
assert isinstance(df, pl.DataFrame)
|
|
558
|
+
|
|
559
|
+
df.write_parquet(
|
|
560
|
+
file=path,
|
|
561
|
+
**kwargs,
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
raise TypeError(f"Unsupported DataFrame backend: {dataframe_backend}")
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def read_parquet(
|
|
568
|
+
path: Path | str,
|
|
569
|
+
dataframe_backend: DataframeBackends = "pandas",
|
|
570
|
+
**kwargs,
|
|
571
|
+
) -> DataFrames:
|
|
572
|
+
path = Path(path)
|
|
573
|
+
|
|
574
|
+
if dataframe_backend == "pandas":
|
|
575
|
+
return pd.read_parquet(
|
|
576
|
+
path=path,
|
|
577
|
+
**kwargs,
|
|
578
|
+
)
|
|
579
|
+
elif dataframe_backend == "polars":
|
|
580
|
+
return pl.read_parquet(
|
|
581
|
+
source=path,
|
|
582
|
+
**kwargs,
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
raise TypeError(f"Unsupported DataFrame backend: {dataframe_backend}")
|
|
586
|
+
|
|
587
|
+
|
|
527
588
|
def setup_dataframes() -> None:
|
|
528
589
|
register_dataframe_accessor(name="utils")(DataframeUtilsAccessor)
|
|
529
590
|
register_series_accessor(name="utils")(SeriesUtilsAccessor)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from contextlib import _GeneratorContextManager
|
|
3
3
|
from sqlite3 import register_adapter
|
|
4
|
-
from typing import Any, Iterator, Optional, Self, Literal, overload
|
|
4
|
+
from typing import Any, Iterator, Mapping, Optional, Self, Literal, overload
|
|
5
5
|
import datetime as _datetime
|
|
6
6
|
import numpy as np
|
|
7
7
|
from pendulum import (
|
|
@@ -453,6 +453,16 @@ class Interval(BaseInterval):
|
|
|
453
453
|
absolute=absolute,
|
|
454
454
|
)
|
|
455
455
|
|
|
456
|
+
def __deepcopy__(
|
|
457
|
+
self,
|
|
458
|
+
_memo: Mapping,
|
|
459
|
+
) -> Self:
|
|
460
|
+
return self.__class__(
|
|
461
|
+
start=self._start,
|
|
462
|
+
end=self._end,
|
|
463
|
+
absolute=self._absolute,
|
|
464
|
+
)
|
|
465
|
+
|
|
456
466
|
@property
|
|
457
467
|
def start(
|
|
458
468
|
self,
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from functools import lru_cache
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Literal
|
|
4
|
-
|
|
5
|
-
import pandas as pd
|
|
6
|
-
from pandas import DataFrame
|
|
7
|
-
|
|
8
|
-
from mayutils.data import CACHE_FOLDER
|
|
9
|
-
from mayutils.data.queries import QUERIES_FOLDERS
|
|
10
|
-
from mayutils.environment.filesystem import encode_path
|
|
11
|
-
from mayutils.objects.hashing import hash_inputs
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def get_query_data(
|
|
15
|
-
query_name: str,
|
|
16
|
-
queries_folders: tuple[Path, ...] = QUERIES_FOLDERS,
|
|
17
|
-
date_columns: tuple[str, ...] = tuple(),
|
|
18
|
-
time_columns: tuple[str, ...] = tuple(),
|
|
19
|
-
numeric_columns: tuple[str, ...] = tuple(),
|
|
20
|
-
cache: bool | Literal["persistent"] = True,
|
|
21
|
-
reader=None,
|
|
22
|
-
backend: Literal["snowflake"] = "snowflake",
|
|
23
|
-
**format_kwargs,
|
|
24
|
-
) -> DataFrame:
|
|
25
|
-
if cache is False:
|
|
26
|
-
_get_query_data.cache_clear()
|
|
27
|
-
|
|
28
|
-
cache_name = f"{encode_path(path=query_name)}_data_{
|
|
29
|
-
hash_inputs(
|
|
30
|
-
query_name=query_name,
|
|
31
|
-
date_columns=date_columns,
|
|
32
|
-
time_columns=time_columns,
|
|
33
|
-
numeric_columns=numeric_columns,
|
|
34
|
-
**format_kwargs,
|
|
35
|
-
)
|
|
36
|
-
}"
|
|
37
|
-
cache_file = CACHE_FOLDER / f"{cache_name}.parquet"
|
|
38
|
-
if cache != "persistent" or not cache_file.is_file():
|
|
39
|
-
query_data = _get_query_data(
|
|
40
|
-
query_name=query_name,
|
|
41
|
-
queries_folders=queries_folders,
|
|
42
|
-
reader=reader,
|
|
43
|
-
**format_kwargs,
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
if cache == "persistent":
|
|
47
|
-
query_data.to_parquet(
|
|
48
|
-
path=cache_file,
|
|
49
|
-
index=True,
|
|
50
|
-
)
|
|
51
|
-
else:
|
|
52
|
-
query_data = pd.read_parquet(
|
|
53
|
-
path=cache_file,
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
return query_data
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@lru_cache
|
|
60
|
-
def _get_query_data() -> DataFrame:
|
|
61
|
-
return DataFrame()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|