python-calamine 0.2.2__cp313-none-win_arm64.whl

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.
@@ -0,0 +1,27 @@
1
+ from ._python_calamine import (
2
+ CalamineError,
3
+ CalamineSheet,
4
+ CalamineWorkbook,
5
+ PasswordError,
6
+ SheetMetadata,
7
+ SheetTypeEnum,
8
+ SheetVisibleEnum,
9
+ WorksheetNotFound,
10
+ XmlError,
11
+ ZipError,
12
+ load_workbook,
13
+ )
14
+
15
+ __all__ = (
16
+ "CalamineError",
17
+ "CalamineSheet",
18
+ "CalamineWorkbook",
19
+ "PasswordError",
20
+ "SheetMetadata",
21
+ "SheetTypeEnum",
22
+ "SheetVisibleEnum",
23
+ "WorksheetNotFound",
24
+ "XmlError",
25
+ "ZipError",
26
+ "load_workbook",
27
+ )
@@ -0,0 +1,131 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ import enum
5
+ import os
6
+ import typing
7
+
8
+ @typing.type_check_only
9
+ class ReadBuffer(typing.Protocol):
10
+ def seek(self, __offset: int, __whence: int = ...) -> int: ...
11
+ def read(self, __size: int = ...) -> bytes | None: ...
12
+
13
+ @typing.final
14
+ class SheetTypeEnum(enum.Enum):
15
+ WorkSheet = ...
16
+ DialogSheet = ...
17
+ MacroSheet = ...
18
+ ChartSheet = ...
19
+ Vba = ...
20
+
21
+ @typing.final
22
+ class SheetVisibleEnum(enum.Enum):
23
+ Visible = ...
24
+ Hidden = ...
25
+ VeryHidden = ...
26
+
27
+ @typing.final
28
+ class SheetMetadata:
29
+ name: str
30
+ typ: SheetTypeEnum
31
+ visible: SheetVisibleEnum
32
+
33
+ def __init__(
34
+ self, name: str, typ: SheetTypeEnum, visible: SheetVisibleEnum
35
+ ) -> None: ...
36
+
37
+ @typing.final
38
+ class CalamineSheet:
39
+ name: str
40
+ @property
41
+ def height(self) -> int: ...
42
+ @property
43
+ def width(self) -> int: ...
44
+ @property
45
+ def total_height(self) -> int: ...
46
+ @property
47
+ def total_width(self) -> int: ...
48
+ @property
49
+ def start(self) -> tuple[int, int] | None: ...
50
+ @property
51
+ def end(self) -> tuple[int, int] | None: ...
52
+ def to_python(
53
+ self, skip_empty_area: bool = True, nrows: int | None = None
54
+ ) -> list[
55
+ list[
56
+ int
57
+ | float
58
+ | str
59
+ | bool
60
+ | datetime.time
61
+ | datetime.date
62
+ | datetime.datetime
63
+ | datetime.timedelta
64
+ ]
65
+ ]:
66
+ """Retunrning data from sheet as list of lists.
67
+
68
+ Parameters
69
+ ----------
70
+ skip_empty_area : bool
71
+ By default, calamine skips empty rows/cols before data.
72
+ For suppress this behaviour, set `skip_empty_area` to `False`.
73
+ """
74
+
75
+ @typing.final
76
+ class CalamineWorkbook:
77
+ path: str | None
78
+ sheet_names: list[str]
79
+ sheets_metadata: list[SheetMetadata]
80
+ @classmethod
81
+ def from_object(
82
+ cls, path_or_filelike: str | os.PathLike | ReadBuffer
83
+ ) -> "CalamineWorkbook":
84
+ """Determining type of pyobject and reading from it.
85
+
86
+ Parameters
87
+ ----------
88
+ path_or_filelike :
89
+ - path (string),
90
+ - pathlike (pathlib.Path),
91
+ - IO (must imlpement read/seek methods).
92
+ """
93
+
94
+ @classmethod
95
+ def from_path(cls, path: str | os.PathLike) -> "CalamineWorkbook":
96
+ """Reading file from path.
97
+
98
+ Parameters
99
+ ----------
100
+ path : path (string)."""
101
+
102
+ @classmethod
103
+ def from_filelike(cls, filelike: ReadBuffer) -> "CalamineWorkbook":
104
+ """Reading file from IO.
105
+
106
+ Parameters
107
+ ----------
108
+ filelike : IO (must imlpement read/seek methods).
109
+ """
110
+
111
+ def get_sheet_by_name(self, name: str) -> CalamineSheet: ...
112
+ def get_sheet_by_index(self, index: int) -> CalamineSheet: ...
113
+
114
+ class CalamineError(Exception): ...
115
+ class PasswordError(CalamineError): ...
116
+ class WorksheetNotFound(CalamineError): ...
117
+ class XmlError(CalamineError): ...
118
+ class ZipError(CalamineError): ...
119
+
120
+ def load_workbook(
121
+ path_or_filelike: str | os.PathLike | ReadBuffer,
122
+ ) -> CalamineWorkbook:
123
+ """Determining type of pyobject and reading from it.
124
+
125
+ Parameters
126
+ ----------
127
+ path_or_filelike :
128
+ - path (string),
129
+ - pathlike (pathlib.Path),
130
+ - IO (must imlpement read/seek methods).
131
+ """
@@ -0,0 +1,136 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import date, datetime, time, timedelta
4
+ from importlib.metadata import version
5
+ from typing import TYPE_CHECKING, Union, cast
6
+
7
+ import pandas as pd
8
+ from packaging.version import Version, parse
9
+ from pandas._typing import Scalar
10
+ from pandas.compat._optional import import_optional_dependency
11
+ from pandas.core.shared_docs import _shared_docs
12
+ from pandas.io.excel import ExcelFile
13
+ from pandas.io.excel._base import ( # type:ignore[attr-defined] # missing in pandas-stubs
14
+ BaseExcelReader,
15
+ )
16
+ from pandas.util._decorators import ( # type:ignore[attr-defined] # missing in pandas-stubs
17
+ doc,
18
+ )
19
+
20
+ if TYPE_CHECKING:
21
+ from pandas._typing import FilePath, ReadBuffer, StorageOptions
22
+ from python_calamine import CalamineSheet, CalamineWorkbook
23
+
24
+ _CellValueT = Union[int, float, str, bool, time, date, datetime, timedelta]
25
+
26
+
27
+ PANDAS_VERSION = parse(version("pandas"))
28
+
29
+
30
+ class CalamineExcelReader(BaseExcelReader):
31
+ book: CalamineWorkbook
32
+
33
+ @doc(storage_options=_shared_docs["storage_options"])
34
+ def __init__(
35
+ self,
36
+ filepath_or_buffer: FilePath | ReadBuffer[bytes],
37
+ storage_options: StorageOptions | None = None,
38
+ engine_kwargs: dict | None = None,
39
+ ) -> None:
40
+ """
41
+ Reader using calamine engine (xlsx/xls/xlsb/ods).
42
+
43
+ Parameters
44
+ ----------
45
+ filepath_or_buffer : str, path to be parsed or
46
+ an open readable stream.
47
+ {storage_options}
48
+ engine_kwargs : dict, optional
49
+ Arbitrary keyword arguments passed to excel engine.
50
+ """
51
+ import_optional_dependency("python_calamine")
52
+ if PANDAS_VERSION >= Version("2.2.0"):
53
+ raise ValueError("Pandas >= 2.2.0 has builtin support of calamine")
54
+ elif PANDAS_VERSION >= Version("2.1.0"):
55
+ super().__init__(
56
+ filepath_or_buffer,
57
+ storage_options=storage_options,
58
+ engine_kwargs=engine_kwargs,
59
+ )
60
+ elif PANDAS_VERSION >= Version("2.0.0"):
61
+ super().__init__(
62
+ filepath_or_buffer,
63
+ storage_options=storage_options,
64
+ )
65
+ else:
66
+ raise ValueError("Pandas >= 2 is only supported")
67
+
68
+ @property
69
+ def _workbook_class(self) -> type[CalamineWorkbook]:
70
+ from python_calamine import CalamineWorkbook
71
+
72
+ return CalamineWorkbook
73
+
74
+ def load_workbook(
75
+ self,
76
+ filepath_or_buffer: FilePath | ReadBuffer[bytes],
77
+ engine_kwargs: dict | None = None,
78
+ ) -> CalamineWorkbook:
79
+ from python_calamine import load_workbook
80
+
81
+ return load_workbook(filepath_or_buffer, **(engine_kwargs or {}))
82
+
83
+ @property
84
+ def sheet_names(self) -> list[str]:
85
+ from python_calamine import SheetTypeEnum
86
+
87
+ return [
88
+ sheet.name
89
+ for sheet in self.book.sheets_metadata
90
+ if sheet.typ == SheetTypeEnum.WorkSheet
91
+ ]
92
+
93
+ def get_sheet_by_name(self, name: str) -> CalamineSheet:
94
+ self.raise_if_bad_sheet_by_name(name)
95
+ return self.book.get_sheet_by_name(name)
96
+
97
+ def get_sheet_by_index(self, index: int) -> CalamineSheet:
98
+ self.raise_if_bad_sheet_by_index(index)
99
+ return self.book.get_sheet_by_index(index)
100
+
101
+ def get_sheet_data(
102
+ self, sheet: CalamineSheet, file_rows_needed: int | None = None
103
+ ) -> list[list[Scalar]]:
104
+ def _convert_cell(value: _CellValueT) -> Scalar:
105
+ if isinstance(value, float):
106
+ val = int(value)
107
+ if val == value:
108
+ return val
109
+ else:
110
+ return value
111
+ elif isinstance(value, date):
112
+ return pd.Timestamp(value)
113
+ elif isinstance(value, timedelta):
114
+ return pd.Timedelta(value)
115
+ elif isinstance(value, time):
116
+ # cast needed here because Scalar doesn't include datetime.time
117
+ return cast(Scalar, value)
118
+
119
+ return value
120
+
121
+ rows: list[list[_CellValueT]] = sheet.to_python(skip_empty_area=False)
122
+ data: list[list[Scalar]] = []
123
+
124
+ for row in rows:
125
+ data.append([_convert_cell(cell) for cell in row])
126
+ if file_rows_needed is not None and len(data) >= file_rows_needed:
127
+ break
128
+
129
+ return data
130
+
131
+
132
+ def pandas_monkeypatch() -> None:
133
+ ExcelFile._engines = { # type:ignore[attr-defined] # missing in pandas-stubs
134
+ "calamine": CalamineExcelReader,
135
+ **ExcelFile._engines, # type:ignore[attr-defined] # missing in pandas-stubs
136
+ }
File without changes
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.3
2
+ Name: python-calamine
3
+ Version: 0.2.2
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: License :: OSI Approved :: MIT License
6
+ Classifier: Programming Language :: Rust
7
+ Classifier: Programming Language :: Python :: 3.8
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ License-File: LICENSE
13
+ Summary: Python binding for Rust's library for reading excel and odf file - calamine
14
+ Home-Page: https://github.com/dimastbk/python-calamine
15
+ Author: Dmitriy <dimastbk@proton.me>
16
+ Author-email: Dmitriy <dimastbk@proton.me>
17
+ License: MIT
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
20
+ Project-URL: Source Code, https://github.com/dimastbk/python-calamine
21
+
22
+ # python-calamine
23
+ [![PyPI - Version](https://img.shields.io/pypi/v/python-calamine)](https://pypi.org/project/python-calamine/)
24
+ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/python-calamine.svg)](https://anaconda.org/conda-forge/python-calamine)
25
+ ![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fdimastbk%2Fpython-calamine%2Fmaster%2Fpyproject.toml)
26
+
27
+
28
+ Python binding for beautiful Rust's library for reading excel and odf file - [calamine](https://github.com/tafia/calamine).
29
+
30
+ ### Is used
31
+ * [calamine](https://github.com/tafia/calamine)
32
+ * [pyo3](https://github.com/PyO3/pyo3)
33
+ * [maturin](https://github.com/PyO3/maturin)
34
+
35
+ ### Installation
36
+ Pypi:
37
+ ```
38
+ pip install python-calamine
39
+ ```
40
+ Conda:
41
+ ```
42
+ conda install -c conda-forge python-calamine
43
+ ```
44
+
45
+ ### Example
46
+ ```python
47
+ from python_calamine import CalamineWorkbook
48
+
49
+ workbook = CalamineWorkbook.from_path("file.xlsx")
50
+ workbook.sheet_names
51
+ # ["Sheet1", "Sheet2"]
52
+
53
+ workbook.get_sheet_by_name("Sheet1").to_python()
54
+ # [
55
+ # ["1", "2", "3", "4", "5", "6", "7"],
56
+ # ["1", "2", "3", "4", "5", "6", "7"],
57
+ # ["1", "2", "3", "4", "5", "6", "7"],
58
+ # ]
59
+ ```
60
+
61
+ By default, calamine skips empty rows/cols before data. For suppress this behaviour, set `skip_empty_area` to `False`.
62
+ ```python
63
+ from python_calamine import CalamineWorkbook
64
+
65
+ workbook = CalamineWorkbook.from_path("file.xlsx").get_sheet_by_name("Sheet1").to_python(skip_empty_area=False)
66
+ # [
67
+ # [", ", ", ", ", ", "],
68
+ # ["1", "2", "3", "4", "5", "6", "7"],
69
+ # ["1", "2", "3", "4", "5", "6", "7"],
70
+ # ["1", "2", "3", "4", "5", "6", "7"],
71
+ # ]
72
+ ```
73
+
74
+ Also, you can use monkeypatch for pandas for use this library as engine in `read_excel()` (only pandas 2.0 and 2.1 are supported).
75
+ Pandas 2.2 and above have built-in support of python-calamine.
76
+ ```python
77
+ from pandas import read_excel
78
+ from python_calamine.pandas import pandas_monkeypatch
79
+
80
+
81
+ pandas_monkeypatch()
82
+
83
+ read_excel("file.xlsx", engine="calamine")
84
+ # 1 2 3 4 5 6 7
85
+ # 0 1 2 3 4 5 6 7
86
+ # 1 1 2 3 4 5 6 7
87
+ ```
88
+
89
+ Also, you can find additional examples in [tests](https://github.com/dimastbk/python-calamine/blob/master/tests/test_base.py).
90
+
@@ -0,0 +1,9 @@
1
+ python_calamine-0.2.2.dist-info/METADATA,sha256=LNN0K4veDPOwviNpcA9VbG7adnav0LpfhHCIhn7qjnA,3215
2
+ python_calamine-0.2.2.dist-info/WHEEL,sha256=OTgXuWyJoWCMfpFuBwcva73pPaGoRRUKq75aMzY1QoI,95
3
+ python_calamine-0.2.2.dist-info/license_files/LICENSE,sha256=cYURXgSnjCTOT2jQ_McTGn-AhDycRqzJa11QzR38Sn4,1086
4
+ python_calamine/pandas.py,sha256=QL-cy_9TMEsjb4bRCNB40tWGPPYlBmUBwEmKBFFuTGc,4734
5
+ python_calamine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ python_calamine/_python_calamine.pyi,sha256=5njO4PkDYexAkwGuBdin7VNhi13c-2PV50_L5r6bmrY,3447
7
+ python_calamine/__init__.py,sha256=Sj9aq7t1YKHHwlsNpXkYinQbgwX9Z6UxRAK9DskMTRM,516
8
+ python_calamine/_python_calamine.cp313-win_arm64.pyd,sha256=KmoisKsfNGnni04-GESFgF79PlIEIt6ss7IxsdCRfm8,1195520
9
+ python_calamine-0.2.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.7.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp313-none-win_arm64
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 dimastbk
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 all
13
+ 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 THE
21
+ SOFTWARE.