stormware 2.0.0__tar.gz → 2.2.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.
- {stormware-2.0.0/stormware.egg-info → stormware-2.2.0}/PKG-INFO +5 -5
- {stormware-2.0.0 → stormware-2.2.0}/requirements/dev.txt +1 -1
- {stormware-2.0.0 → stormware-2.2.0}/requirements/dev.txt.lock +25 -23
- {stormware-2.0.0 → stormware-2.2.0}/requirements/docs.txt +1 -1
- {stormware-2.0.0 → stormware-2.2.0}/requirements/docs.txt.lock +19 -17
- stormware-2.2.0/requirements/extras/amazon.txt +2 -0
- {stormware-2.0.0 → stormware-2.2.0}/requirements/extras/google.txt +2 -2
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/gmail.py +50 -8
- {stormware-2.0.0 → stormware-2.2.0/stormware.egg-info}/PKG-INFO +5 -5
- {stormware-2.0.0 → stormware-2.2.0}/stormware.egg-info/requires.txt +4 -4
- stormware-2.0.0/requirements/extras/amazon.txt +0 -2
- {stormware-2.0.0 → stormware-2.2.0}/.copier-answers.yml +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/LICENSE.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/MANIFEST.in +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/README.rst +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/pyproject.toml +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/requirements/build.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/requirements/build.txt.lock +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/requirements/core.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/requirements/extras/facebook.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/setup.cfg +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/__init__.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/amazon/__init__.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/amazon/auth.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/amazon/secrets.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/auth.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/client_manager.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/facebook.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/__init__.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/auth.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/bigquery.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/drive.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/secrets.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/google/sheets.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/py.typed +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware/secrets.py +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware.egg-info/SOURCES.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware.egg-info/dependency_links.txt +0 -0
- {stormware-2.0.0 → stormware-2.2.0}/stormware.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: stormware
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: API connectors for data analysis and task automation
|
|
5
5
|
Author-email: Logikal GmbH <contact@logikal.io>
|
|
6
6
|
License: Copyright 2023 Logikal GmbH
|
|
@@ -41,15 +41,15 @@ Requires-Dist: pandas[performance]~=2.2
|
|
|
41
41
|
Requires-Dist: pandas-stubs~=2.2
|
|
42
42
|
Requires-Dist: xdg-base-dirs~=6.0
|
|
43
43
|
Provides-Extra: google
|
|
44
|
-
Requires-Dist: google-api-python-client==2.
|
|
44
|
+
Requires-Dist: google-api-python-client==2.162.0; extra == "google"
|
|
45
45
|
Requires-Dist: google-auth==2.38.0; extra == "google"
|
|
46
|
-
Requires-Dist: google-cloud-bigquery[pandas]
|
|
46
|
+
Requires-Dist: google-cloud-bigquery[pandas]==3.29.0; extra == "google"
|
|
47
47
|
Requires-Dist: google-cloud-bigquery-storage~=2.28; extra == "google"
|
|
48
48
|
Requires-Dist: google-cloud-secret-manager==2.23.1; extra == "google"
|
|
49
49
|
Requires-Dist: google-crc32c==1.6.0; extra == "google"
|
|
50
50
|
Provides-Extra: amazon
|
|
51
|
-
Requires-Dist: boto3==1.
|
|
52
|
-
Requires-Dist: boto3-stubs==1.
|
|
51
|
+
Requires-Dist: boto3==1.37.4; extra == "amazon"
|
|
52
|
+
Requires-Dist: boto3-stubs==1.37.4; extra == "amazon"
|
|
53
53
|
Provides-Extra: facebook
|
|
54
54
|
Requires-Dist: facebook-business==22.0.2; extra == "facebook"
|
|
55
55
|
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
## DO NOT EDIT THIS FILE.
|
|
4
4
|
## This is a locked requirements file generated by pyorbs.
|
|
5
5
|
##
|
|
6
|
-
## Requirements hash:
|
|
6
|
+
## Requirements hash: cc9601c96bdeb06c8a9dc0c1317bbc8d9d14698261e2a0362edcf8e2fa7a1cf6
|
|
7
7
|
##
|
|
8
8
|
###################################################################################################
|
|
9
9
|
-e .
|
|
10
10
|
aiohappyeyeballs==2.4.6
|
|
11
|
-
aiohttp==3.11.
|
|
11
|
+
aiohttp==3.11.13
|
|
12
12
|
aiosignal==1.3.2
|
|
13
13
|
alabaster==1.0.0
|
|
14
14
|
astroid==3.3.8
|
|
@@ -18,10 +18,10 @@ babel==2.17.0
|
|
|
18
18
|
bandit==1.8.3
|
|
19
19
|
beautifulsoup4==4.13.3
|
|
20
20
|
bleach==6.2.0
|
|
21
|
-
boto3==1.
|
|
22
|
-
boto3-stubs==1.
|
|
23
|
-
botocore==1.
|
|
24
|
-
botocore-stubs==1.
|
|
21
|
+
boto3==1.37.4
|
|
22
|
+
boto3-stubs==1.37.4
|
|
23
|
+
botocore==1.37.4
|
|
24
|
+
botocore-stubs==1.37.1
|
|
25
25
|
Bottleneck==1.4.2
|
|
26
26
|
build==1.2.2
|
|
27
27
|
cachetools==5.5.2
|
|
@@ -32,11 +32,11 @@ codespell==2.4.1
|
|
|
32
32
|
colorama==0.4.6
|
|
33
33
|
comm==0.2.2
|
|
34
34
|
coverage==7.6.12
|
|
35
|
-
cryptography==44.0.
|
|
35
|
+
cryptography==44.0.2
|
|
36
36
|
curlify==2.2.1
|
|
37
37
|
db-dtypes==1.4.1
|
|
38
38
|
debugpy==1.8.12
|
|
39
|
-
decorator==5.2.
|
|
39
|
+
decorator==5.2.1
|
|
40
40
|
defusedxml==0.7.1
|
|
41
41
|
dill==0.3.9
|
|
42
42
|
docutils==0.21.2
|
|
@@ -47,7 +47,7 @@ fastjsonschema==2.21.1
|
|
|
47
47
|
filelock==3.17.0
|
|
48
48
|
frozenlist==1.5.0
|
|
49
49
|
google-api-core==2.24.1
|
|
50
|
-
google-api-python-client==2.
|
|
50
|
+
google-api-python-client==2.162.0
|
|
51
51
|
google-auth==2.38.0
|
|
52
52
|
google-auth-httplib2==0.2.0
|
|
53
53
|
google-cloud-bigquery==3.29.0
|
|
@@ -58,22 +58,23 @@ google-crc32c==1.6.0
|
|
|
58
58
|
google-resumable-media==2.7.2
|
|
59
59
|
googleapis-common-protos==1.68.0
|
|
60
60
|
grpc-google-iam-v1==0.14.0
|
|
61
|
-
grpcio==1.
|
|
62
|
-
grpcio-status==1.
|
|
61
|
+
grpcio==1.71.0rc2
|
|
62
|
+
grpcio-status==1.71.0rc2
|
|
63
63
|
httplib2==0.22.0
|
|
64
64
|
id==1.5.0
|
|
65
65
|
idna==3.10
|
|
66
66
|
imagesize==1.4.1
|
|
67
67
|
iniconfig==2.0.0
|
|
68
68
|
ipykernel==6.29.5
|
|
69
|
-
ipython==
|
|
69
|
+
ipython==9.0.0
|
|
70
|
+
ipython_pygments_lexers==1.1.1
|
|
70
71
|
ipywidgets==8.1.5
|
|
71
|
-
isort==6.0.
|
|
72
|
+
isort==6.0.1
|
|
72
73
|
jaraco.classes==3.4.0
|
|
73
74
|
jaraco.context==6.0.1
|
|
74
75
|
jaraco.functools==4.1.0
|
|
75
76
|
jedi==0.19.2
|
|
76
|
-
jeepney==0.
|
|
77
|
+
jeepney==0.9.0
|
|
77
78
|
Jinja2==3.1.5
|
|
78
79
|
jmespath==1.0.1
|
|
79
80
|
jsonschema==4.23.0
|
|
@@ -85,7 +86,7 @@ jupyterlab_pygments==0.3.0
|
|
|
85
86
|
jupyterlab_widgets==3.0.13
|
|
86
87
|
keyring==25.6.0
|
|
87
88
|
llvmlite==0.44.0
|
|
88
|
-
logikal-docs==1.2.
|
|
89
|
+
logikal-docs==1.2.2
|
|
89
90
|
logikal-utils==1.4.0
|
|
90
91
|
markdown-it-py==3.0.0
|
|
91
92
|
MarkupSafe==3.0.2
|
|
@@ -101,7 +102,7 @@ nbclient==0.10.2
|
|
|
101
102
|
nbconvert==7.16.6
|
|
102
103
|
nbformat==5.10.4
|
|
103
104
|
nest-asyncio==1.6.0
|
|
104
|
-
nh3==0.2.
|
|
105
|
+
nh3==0.2.21
|
|
105
106
|
numba==0.61.0
|
|
106
107
|
numexpr==2.10.2
|
|
107
108
|
numpy==2.1.3
|
|
@@ -117,7 +118,7 @@ pip==25.0.1
|
|
|
117
118
|
pip-licenses==5.0.0
|
|
118
119
|
platformdirs==4.3.6
|
|
119
120
|
pluggy==1.5.0
|
|
120
|
-
prettytable==3.
|
|
121
|
+
prettytable==3.15.1
|
|
121
122
|
prompt_toolkit==3.0.50
|
|
122
123
|
propcache==0.3.0
|
|
123
124
|
proto-plus==1.26.0
|
|
@@ -139,7 +140,7 @@ pyparsing==3.2.1
|
|
|
139
140
|
pyproject_hooks==1.2.0
|
|
140
141
|
pytest==8.3.4
|
|
141
142
|
pytest-cov==6.0.0
|
|
142
|
-
pytest-logikal==4.0.
|
|
143
|
+
pytest-logikal==4.0.5
|
|
143
144
|
pytest-mock==3.14.0
|
|
144
145
|
pytest-mypy==0.10.3
|
|
145
146
|
pytest-xdist==3.6.1
|
|
@@ -153,16 +154,17 @@ requests==2.32.3
|
|
|
153
154
|
requests-toolbelt==1.0.0
|
|
154
155
|
rfc3986==2.0.0
|
|
155
156
|
rich==13.9.4
|
|
157
|
+
roman-numerals-py==3.1.0
|
|
156
158
|
rpds-py==0.23.1
|
|
157
159
|
rsa==4.9
|
|
158
|
-
s3transfer==0.11.
|
|
160
|
+
s3transfer==0.11.3
|
|
159
161
|
SecretStorage==3.3.3
|
|
160
|
-
setuptools==75.8.
|
|
162
|
+
setuptools==75.8.2
|
|
161
163
|
six==1.17.0
|
|
162
164
|
snowballstemmer==2.2.0
|
|
163
165
|
soupsieve==2.6
|
|
164
|
-
Sphinx==8.1
|
|
165
|
-
sphinx-rtd-theme==3.0.
|
|
166
|
+
Sphinx==8.2.1
|
|
167
|
+
sphinx-rtd-theme==3.0.2
|
|
166
168
|
sphinxcontrib-applehelp==2.0.0
|
|
167
169
|
sphinxcontrib-devhelp==2.0.0
|
|
168
170
|
sphinxcontrib-htmlhelp==2.1.0
|
|
@@ -181,7 +183,7 @@ traitlets==5.14.3
|
|
|
181
183
|
twine==6.1.0
|
|
182
184
|
types-awscrt==0.23.10
|
|
183
185
|
types-pytz==2025.1.0.20250204
|
|
184
|
-
types-s3transfer==0.11.
|
|
186
|
+
types-s3transfer==0.11.3
|
|
185
187
|
typing_extensions==4.12.2
|
|
186
188
|
tzdata==2025.1
|
|
187
189
|
uritemplate==4.1.1
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
## DO NOT EDIT THIS FILE.
|
|
4
4
|
## This is a locked requirements file generated by pyorbs.
|
|
5
5
|
##
|
|
6
|
-
## Requirements hash:
|
|
6
|
+
## Requirements hash: c217d81e73279da34df380e3d7b016bc2c11457d6af4fea4497deea27fb05a27
|
|
7
7
|
##
|
|
8
8
|
###################################################################################################
|
|
9
9
|
-e .
|
|
10
10
|
aiohappyeyeballs==2.4.6
|
|
11
|
-
aiohttp==3.11.
|
|
11
|
+
aiohttp==3.11.13
|
|
12
12
|
aiosignal==1.3.2
|
|
13
13
|
alabaster==1.0.0
|
|
14
14
|
asttokens==3.0.0
|
|
@@ -16,10 +16,10 @@ attrs==25.1.0
|
|
|
16
16
|
babel==2.17.0
|
|
17
17
|
beautifulsoup4==4.13.3
|
|
18
18
|
bleach==6.2.0
|
|
19
|
-
boto3==1.
|
|
20
|
-
boto3-stubs==1.
|
|
21
|
-
botocore==1.
|
|
22
|
-
botocore-stubs==1.
|
|
19
|
+
boto3==1.37.4
|
|
20
|
+
boto3-stubs==1.37.4
|
|
21
|
+
botocore==1.37.4
|
|
22
|
+
botocore-stubs==1.37.1
|
|
23
23
|
Bottleneck==1.4.2
|
|
24
24
|
cachetools==5.5.2
|
|
25
25
|
certifi==2025.1.31
|
|
@@ -28,7 +28,7 @@ comm==0.2.2
|
|
|
28
28
|
curlify==2.2.1
|
|
29
29
|
db-dtypes==1.4.1
|
|
30
30
|
debugpy==1.8.12
|
|
31
|
-
decorator==5.2.
|
|
31
|
+
decorator==5.2.1
|
|
32
32
|
defusedxml==0.7.1
|
|
33
33
|
docutils==0.21.2
|
|
34
34
|
executing==2.2.0
|
|
@@ -36,7 +36,7 @@ facebook_business==22.0.2
|
|
|
36
36
|
fastjsonschema==2.21.1
|
|
37
37
|
frozenlist==1.5.0
|
|
38
38
|
google-api-core==2.24.1
|
|
39
|
-
google-api-python-client==2.
|
|
39
|
+
google-api-python-client==2.162.0
|
|
40
40
|
google-auth==2.38.0
|
|
41
41
|
google-auth-httplib2==0.2.0
|
|
42
42
|
google-cloud-bigquery==3.29.0
|
|
@@ -47,13 +47,14 @@ google-crc32c==1.6.0
|
|
|
47
47
|
google-resumable-media==2.7.2
|
|
48
48
|
googleapis-common-protos==1.68.0
|
|
49
49
|
grpc-google-iam-v1==0.14.0
|
|
50
|
-
grpcio==1.
|
|
51
|
-
grpcio-status==1.
|
|
50
|
+
grpcio==1.71.0rc2
|
|
51
|
+
grpcio-status==1.71.0rc2
|
|
52
52
|
httplib2==0.22.0
|
|
53
53
|
idna==3.10
|
|
54
54
|
imagesize==1.4.1
|
|
55
55
|
ipykernel==6.29.5
|
|
56
|
-
ipython==
|
|
56
|
+
ipython==9.0.0
|
|
57
|
+
ipython_pygments_lexers==1.1.1
|
|
57
58
|
ipywidgets==8.1.5
|
|
58
59
|
jedi==0.19.2
|
|
59
60
|
Jinja2==3.1.5
|
|
@@ -66,7 +67,7 @@ jupyter_core==5.7.2
|
|
|
66
67
|
jupyterlab_pygments==0.3.0
|
|
67
68
|
jupyterlab_widgets==3.0.13
|
|
68
69
|
llvmlite==0.44.0
|
|
69
|
-
logikal-docs==1.2.
|
|
70
|
+
logikal-docs==1.2.2
|
|
70
71
|
logikal-utils==1.4.0
|
|
71
72
|
MarkupSafe==3.0.2
|
|
72
73
|
matplotlib-inline==0.1.7
|
|
@@ -105,15 +106,16 @@ pytz==2025.1
|
|
|
105
106
|
pyzmq==26.2.1
|
|
106
107
|
referencing==0.36.2
|
|
107
108
|
requests==2.32.3
|
|
109
|
+
roman-numerals-py==3.1.0
|
|
108
110
|
rpds-py==0.23.1
|
|
109
111
|
rsa==4.9
|
|
110
|
-
s3transfer==0.11.
|
|
111
|
-
setuptools==75.8.
|
|
112
|
+
s3transfer==0.11.3
|
|
113
|
+
setuptools==75.8.2
|
|
112
114
|
six==1.17.0
|
|
113
115
|
snowballstemmer==2.2.0
|
|
114
116
|
soupsieve==2.6
|
|
115
|
-
Sphinx==8.1
|
|
116
|
-
sphinx-rtd-theme==3.0.
|
|
117
|
+
Sphinx==8.2.1
|
|
118
|
+
sphinx-rtd-theme==3.0.2
|
|
117
119
|
sphinxcontrib-applehelp==2.0.0
|
|
118
120
|
sphinxcontrib-devhelp==2.0.0
|
|
119
121
|
sphinxcontrib-htmlhelp==2.1.0
|
|
@@ -128,7 +130,7 @@ tornado==6.4.2
|
|
|
128
130
|
traitlets==5.14.3
|
|
129
131
|
types-awscrt==0.23.10
|
|
130
132
|
types-pytz==2025.1.0.20250204
|
|
131
|
-
types-s3transfer==0.11.
|
|
133
|
+
types-s3transfer==0.11.3
|
|
132
134
|
typing_extensions==4.12.2
|
|
133
135
|
tzdata==2025.1
|
|
134
136
|
uritemplate==4.1.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
google-api-python-client==2.
|
|
1
|
+
google-api-python-client==2.162.0
|
|
2
2
|
google-auth==2.38.0
|
|
3
|
-
google-cloud-bigquery[pandas]
|
|
3
|
+
google-cloud-bigquery[pandas]==3.29.0
|
|
4
4
|
google-cloud-bigquery-storage~=2.28
|
|
5
5
|
google-cloud-secret-manager==2.23.1
|
|
6
6
|
google-crc32c==1.6.0
|
|
@@ -5,6 +5,7 @@ Gmail API connector.
|
|
|
5
5
|
# - Google API Python Client Library: https://googleapis.github.io/google-api-python-client/
|
|
6
6
|
# - Gmail API: https://developers.google.com/gmail/api
|
|
7
7
|
import base64
|
|
8
|
+
import email
|
|
8
9
|
from dataclasses import dataclass
|
|
9
10
|
from datetime import datetime, timezone
|
|
10
11
|
from logging import getLogger
|
|
@@ -19,7 +20,7 @@ from stormware.google.auth import GCPAuth
|
|
|
19
20
|
logger = getLogger(__name__)
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
@dataclass
|
|
23
|
+
@dataclass(order=True, kw_only=True)
|
|
23
24
|
class Label:
|
|
24
25
|
"""
|
|
25
26
|
Represents a label.
|
|
@@ -28,7 +29,7 @@ class Label:
|
|
|
28
29
|
name: str | None = None
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
@dataclass
|
|
32
|
+
@dataclass(order=True, kw_only=True)
|
|
32
33
|
class Attachment:
|
|
33
34
|
"""
|
|
34
35
|
Represents an email message attachment.
|
|
@@ -39,13 +40,25 @@ class Attachment:
|
|
|
39
40
|
mime_type: str | None
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
@dataclass(order=True)
|
|
43
|
+
@dataclass(order=True, kw_only=True)
|
|
44
|
+
class Address:
|
|
45
|
+
"""
|
|
46
|
+
Represents an email address.
|
|
47
|
+
"""
|
|
48
|
+
email: str
|
|
49
|
+
display_name: str | None = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(order=True, kw_only=True)
|
|
43
53
|
class Message: # pylint: disable=too-many-instance-attributes
|
|
44
54
|
"""
|
|
45
55
|
Represents an email message.
|
|
46
56
|
"""
|
|
47
57
|
id: str
|
|
48
58
|
thread_id: str | None = None
|
|
59
|
+
sender: Address | None = None
|
|
60
|
+
to: list[Address] | None = None
|
|
61
|
+
cc: list[Address] | None = None
|
|
49
62
|
subject: str | None = None
|
|
50
63
|
plain_text: str | None = None
|
|
51
64
|
html_text: str | None = None
|
|
@@ -68,7 +81,7 @@ class Message: # pylint: disable=too-many-instance-attributes
|
|
|
68
81
|
self.add_part(subpart)
|
|
69
82
|
|
|
70
83
|
|
|
71
|
-
@dataclass
|
|
84
|
+
@dataclass(kw_only=True)
|
|
72
85
|
class Query: # pylint: disable=too-many-instance-attributes
|
|
73
86
|
"""
|
|
74
87
|
Represents a Gmail `search query <https://support.google.com/mail/answer/7190?hl=en>`_.
|
|
@@ -131,6 +144,19 @@ class Gmail(ClientManager[Any]):
|
|
|
131
144
|
def create_client(self) -> Any:
|
|
132
145
|
return build('gmail', 'v1', credentials=self.auth.credentials(), cache_discovery=False)
|
|
133
146
|
|
|
147
|
+
def labels(self, *, user_id: str = 'me') -> list[Label]:
|
|
148
|
+
"""
|
|
149
|
+
Load labels.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
user_id: The user ID to use.
|
|
153
|
+
|
|
154
|
+
"""
|
|
155
|
+
response = self.client.users().labels().list( # pylint: disable=no-member
|
|
156
|
+
userId=user_id
|
|
157
|
+
).execute()
|
|
158
|
+
return [Label(id=label['id'], name=label['name']) for label in response.get('labels', [])]
|
|
159
|
+
|
|
134
160
|
def messages(self, query: Query, *, user_id: str = 'me') -> list[Message]:
|
|
135
161
|
"""
|
|
136
162
|
Load messages that match a given query.
|
|
@@ -149,7 +175,7 @@ class Gmail(ClientManager[Any]):
|
|
|
149
175
|
while True: # pylint: disable=while-used
|
|
150
176
|
page += 1
|
|
151
177
|
logger.debug(f'Loading page {page}')
|
|
152
|
-
response = self.client.users().messages().list(
|
|
178
|
+
response = self.client.users().messages().list(
|
|
153
179
|
q=query_str,
|
|
154
180
|
userId=user_id,
|
|
155
181
|
labelIds=[label.id for label in query.labels or []],
|
|
@@ -164,6 +190,13 @@ class Gmail(ClientManager[Any]):
|
|
|
164
190
|
for message in messages
|
|
165
191
|
]
|
|
166
192
|
|
|
193
|
+
@staticmethod
|
|
194
|
+
def _parse_address(addresses: str) -> list[Address]:
|
|
195
|
+
return [
|
|
196
|
+
Address(email=field[1], display_name=field[0] or None)
|
|
197
|
+
for field in email.utils.getaddresses([addresses])
|
|
198
|
+
]
|
|
199
|
+
|
|
167
200
|
def message(self, message: Message, *, user_id: str = 'me') -> Message:
|
|
168
201
|
"""
|
|
169
202
|
Load a specific message.
|
|
@@ -189,14 +222,23 @@ class Gmail(ClientManager[Any]):
|
|
|
189
222
|
message = Message(
|
|
190
223
|
id=response['id'],
|
|
191
224
|
thread_id=response.get('threadId'),
|
|
225
|
+
to=[],
|
|
226
|
+
cc=[],
|
|
192
227
|
timestamp=datetime.fromtimestamp(int(response['internalDate']) / 1000, timezone.utc),
|
|
193
228
|
labels=[Label(id=label_id) for label_id in response.get('labelIds')],
|
|
194
229
|
attachments=[],
|
|
195
230
|
)
|
|
196
231
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
232
|
+
# Process headers
|
|
233
|
+
for header in response.get('payload', {}).get('headers', []):
|
|
234
|
+
if header['name'].lower() == 'from':
|
|
235
|
+
message.sender = self._parse_address(header['value'])[0]
|
|
236
|
+
elif header['name'].lower() == 'to':
|
|
237
|
+
message.to = self._parse_address(header['value'])
|
|
238
|
+
elif header['name'].lower() == 'cc':
|
|
239
|
+
message.cc = self._parse_address(header['value'])
|
|
240
|
+
elif header['name'].lower() == 'subject':
|
|
241
|
+
message.subject = header['value']
|
|
200
242
|
|
|
201
243
|
# Process message parts
|
|
202
244
|
for part in response.get('payload', {}).get('parts', []):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: stormware
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: API connectors for data analysis and task automation
|
|
5
5
|
Author-email: Logikal GmbH <contact@logikal.io>
|
|
6
6
|
License: Copyright 2023 Logikal GmbH
|
|
@@ -41,15 +41,15 @@ Requires-Dist: pandas[performance]~=2.2
|
|
|
41
41
|
Requires-Dist: pandas-stubs~=2.2
|
|
42
42
|
Requires-Dist: xdg-base-dirs~=6.0
|
|
43
43
|
Provides-Extra: google
|
|
44
|
-
Requires-Dist: google-api-python-client==2.
|
|
44
|
+
Requires-Dist: google-api-python-client==2.162.0; extra == "google"
|
|
45
45
|
Requires-Dist: google-auth==2.38.0; extra == "google"
|
|
46
|
-
Requires-Dist: google-cloud-bigquery[pandas]
|
|
46
|
+
Requires-Dist: google-cloud-bigquery[pandas]==3.29.0; extra == "google"
|
|
47
47
|
Requires-Dist: google-cloud-bigquery-storage~=2.28; extra == "google"
|
|
48
48
|
Requires-Dist: google-cloud-secret-manager==2.23.1; extra == "google"
|
|
49
49
|
Requires-Dist: google-crc32c==1.6.0; extra == "google"
|
|
50
50
|
Provides-Extra: amazon
|
|
51
|
-
Requires-Dist: boto3==1.
|
|
52
|
-
Requires-Dist: boto3-stubs==1.
|
|
51
|
+
Requires-Dist: boto3==1.37.4; extra == "amazon"
|
|
52
|
+
Requires-Dist: boto3-stubs==1.37.4; extra == "amazon"
|
|
53
53
|
Provides-Extra: facebook
|
|
54
54
|
Requires-Dist: facebook-business==22.0.2; extra == "facebook"
|
|
55
55
|
|
|
@@ -4,16 +4,16 @@ pandas-stubs~=2.2
|
|
|
4
4
|
xdg-base-dirs~=6.0
|
|
5
5
|
|
|
6
6
|
[amazon]
|
|
7
|
-
boto3==1.
|
|
8
|
-
boto3-stubs==1.
|
|
7
|
+
boto3==1.37.4
|
|
8
|
+
boto3-stubs==1.37.4
|
|
9
9
|
|
|
10
10
|
[facebook]
|
|
11
11
|
facebook-business==22.0.2
|
|
12
12
|
|
|
13
13
|
[google]
|
|
14
|
-
google-api-python-client==2.
|
|
14
|
+
google-api-python-client==2.162.0
|
|
15
15
|
google-auth==2.38.0
|
|
16
|
-
google-cloud-bigquery[pandas]
|
|
16
|
+
google-cloud-bigquery[pandas]==3.29.0
|
|
17
17
|
google-cloud-bigquery-storage~=2.28
|
|
18
18
|
google-cloud-secret-manager==2.23.1
|
|
19
19
|
google-crc32c==1.6.0
|
|
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
|