email-core-lib 0.0.0.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.
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright 2022 Shay Tesler
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to pay, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ include requirements.txt
2
+ include LICENSE
3
+ include README.md
4
+
5
+
6
+ global-exclude *.pyc
7
+ global-exclude __pycache__
8
+ recursive-include hydra_plugins/* *.yaml
9
+ recursive-include email_core_lib/* *.yaml
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: email_core_lib
3
+ Version: 0.0.0.1
4
+ Summary: Email Core Lib
5
+ Home-page: https://github.com/shay-te/email-core-lib/
6
+ Author: Shay Tessler
7
+ Author-email: shay.te@gmail.com
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Programming Language :: Python :: 3.7
11
+ Classifier: Topic :: Software Development
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE_2022_4_19
15
+ Requires-Dist: eventlet
16
+ Requires-Dist: mailchimp-transactional
17
+ Requires-Dist: sib-api-v3-sdk
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: license-file
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ # EmailCoreLib
31
+ `EmailCoreLib` uses [Celery](https://docs.celeryq.dev/en/stable/getting-started/introduction.html) and [MailChimp](https://mailchimp.com/) to receive data and send emails.
32
+ It uses `Celery` to listen to a queue and receive data over it, and `MailChimp` is used to fire emails using their [Transactional Email](https://mailchimp.com/features/transactional-email/) service.
33
+
34
+ ## Services
35
+ - Send Emails using MailChimp
36
+ - Starts Celery Worker to handle requests
37
+
38
+ ## Config
39
+ ```yaml
40
+ core_lib:
41
+ email_core_lib:
42
+ amqp:
43
+ url:
44
+ protocol: amqp
45
+ username: ${oc.env:AMQP_USERNAME}
46
+ password: ${oc.env:AMQP_PASSWORD}
47
+ host: ${oc.env:AMQP_HOST}
48
+ port: ${oc.env:AMQP_PORT}
49
+ client:
50
+ _target_: email_core_lib.client.mailchimp_client.MailChimpClient
51
+ api_key: your_mailchimp_transactional_api_key
52
+ ```
53
+
54
+ ## celery_main.py
55
+ This is the main file that will start the `Celery` worker and initialize the `EmailCoreLib`. As soon as a task is
56
+ dispatched for `task.send` it will use the `MailchimpTransactional` client to send the email.
57
+
58
+ ## EmailCoreLib
59
+ ```python
60
+ class EmailCoreLib(CoreLib):
61
+ def __init__(self, conf: DictConfig):
62
+ super().__init__()
63
+ self.config = conf
64
+ self.mailchimp = instantiate_config(self.config.core_lib.email_core_lib.client)
65
+ ```
66
+ Uses `CoreLib`'s `instantiate_config` that will instantiate the `MailChimpClient` from the config yaml.
67
+
68
+ ## MailChimp Client
69
+ This client will be initialized as soon as the `Celery` worker has started and the `EmailCoreLib` is initialized
70
+
71
+ ### Functions
72
+ ```python
73
+ def send(self, template_name: str, params: dict):
74
+ ```
75
+
76
+ `template_name` (*str*): Name of the saved template in your MailChimp Transactional account
77
+
78
+ `params` (*dict*): A `dict` of variables as keys and their values that are saved in the template to be replaced.
79
+
80
+ ## Example
81
+ ```python
82
+ import hydra
83
+ from celery import Celery
84
+
85
+ hydra.initialize(config_path='config_path', caller_stack_depth=1)
86
+ cfg = hydra.compose('config.yaml')
87
+
88
+ app = Celery()
89
+ app.config_from_object(cfg.core_lib.email_core_lib.amqp.url)
90
+ app.autodiscover_tasks()
91
+
92
+ app.send_task('task.send',
93
+ ['register_complete', {'email': 'john@example.com', 'plan': 'some plan'}]
94
+ )
95
+ ```
96
+ ## License
97
+ Licenced under [MIT](https://github.com/shay-te/email-core-lib/blob/master/LICENSE_2022_4_19)
@@ -0,0 +1,68 @@
1
+ # EmailCoreLib
2
+ `EmailCoreLib` uses [Celery](https://docs.celeryq.dev/en/stable/getting-started/introduction.html) and [MailChimp](https://mailchimp.com/) to receive data and send emails.
3
+ It uses `Celery` to listen to a queue and receive data over it, and `MailChimp` is used to fire emails using their [Transactional Email](https://mailchimp.com/features/transactional-email/) service.
4
+
5
+ ## Services
6
+ - Send Emails using MailChimp
7
+ - Starts Celery Worker to handle requests
8
+
9
+ ## Config
10
+ ```yaml
11
+ core_lib:
12
+ email_core_lib:
13
+ amqp:
14
+ url:
15
+ protocol: amqp
16
+ username: ${oc.env:AMQP_USERNAME}
17
+ password: ${oc.env:AMQP_PASSWORD}
18
+ host: ${oc.env:AMQP_HOST}
19
+ port: ${oc.env:AMQP_PORT}
20
+ client:
21
+ _target_: email_core_lib.client.mailchimp_client.MailChimpClient
22
+ api_key: your_mailchimp_transactional_api_key
23
+ ```
24
+
25
+ ## celery_main.py
26
+ This is the main file that will start the `Celery` worker and initialize the `EmailCoreLib`. As soon as a task is
27
+ dispatched for `task.send` it will use the `MailchimpTransactional` client to send the email.
28
+
29
+ ## EmailCoreLib
30
+ ```python
31
+ class EmailCoreLib(CoreLib):
32
+ def __init__(self, conf: DictConfig):
33
+ super().__init__()
34
+ self.config = conf
35
+ self.mailchimp = instantiate_config(self.config.core_lib.email_core_lib.client)
36
+ ```
37
+ Uses `CoreLib`'s `instantiate_config` that will instantiate the `MailChimpClient` from the config yaml.
38
+
39
+ ## MailChimp Client
40
+ This client will be initialized as soon as the `Celery` worker has started and the `EmailCoreLib` is initialized
41
+
42
+ ### Functions
43
+ ```python
44
+ def send(self, template_name: str, params: dict):
45
+ ```
46
+
47
+ `template_name` (*str*): Name of the saved template in your MailChimp Transactional account
48
+
49
+ `params` (*dict*): A `dict` of variables as keys and their values that are saved in the template to be replaced.
50
+
51
+ ## Example
52
+ ```python
53
+ import hydra
54
+ from celery import Celery
55
+
56
+ hydra.initialize(config_path='config_path', caller_stack_depth=1)
57
+ cfg = hydra.compose('config.yaml')
58
+
59
+ app = Celery()
60
+ app.config_from_object(cfg.core_lib.email_core_lib.amqp.url)
61
+ app.autodiscover_tasks()
62
+
63
+ app.send_task('task.send',
64
+ ['register_complete', {'email': 'john@example.com', 'plan': 'some plan'}]
65
+ )
66
+ ```
67
+ ## License
68
+ Licenced under [MIT](https://github.com/shay-te/email-core-lib/blob/master/LICENSE_2022_4_19)
@@ -0,0 +1,2 @@
1
+ # Version of the core_lib
2
+ __version__ = '0.0.0.1'
@@ -0,0 +1,44 @@
1
+ import logging
2
+
3
+ import mailchimp_transactional as MailchimpTransactional
4
+ from mailchimp_transactional.api_client import ApiClientError
5
+
6
+
7
+ class MailChimpClient:
8
+ def __init__(self, api_key: str):
9
+ self.logger = logging.getLogger(self.__class__.__name__)
10
+ self.api_key = api_key
11
+ self.mailchimp = MailchimpTransactional.Client(self.api_key)
12
+
13
+ def send(self, template_name: str, params: dict):
14
+ template_content = []
15
+ for key, val in params.items():
16
+ if key != 'email':
17
+ template_content.append({
18
+ 'name': key,
19
+ 'content': str(val)
20
+ })
21
+ message = {
22
+ "to": [
23
+ {
24
+ "email": params['email'],
25
+ "type": "to"
26
+ }
27
+ ],
28
+ "merge_language": "handlebars",
29
+ "merge": True,
30
+ "global_merge_vars": template_content,
31
+ }
32
+ try:
33
+ response = self.mailchimp.messages.send_template(
34
+ {"template_name": template_name, "template_content": template_content, "message": message}
35
+ )
36
+ if response and len(response) > 0:
37
+ return True if response[0].get('status') == 'sent' else False
38
+ return False
39
+ except ApiClientError as error:
40
+ self.logger.error(f'An exception occurred: {error.text}')
41
+ self.logger.error(error)
42
+ except Exception as error:
43
+ self.logger.error(error)
44
+ return False
@@ -0,0 +1,47 @@
1
+ import logging
2
+
3
+ import requests
4
+ import sib_api_v3_sdk
5
+ from sib_api_v3_sdk.rest import ApiException
6
+
7
+ SENDER = {"name": "una", "email": "noreply@getuna.ai"}
8
+
9
+
10
+ class SendInBlueClient:
11
+ def __init__(self, api_key: str, slack_email_error_url: str):
12
+ self.logger = logging.getLogger(self.__class__.__name__)
13
+ self.api_key = api_key
14
+ self._slack_email_error_url = slack_email_error_url
15
+ configuration = sib_api_v3_sdk.Configuration()
16
+ configuration.api_key['api-key'] = api_key
17
+ self.api_instance = sib_api_v3_sdk.TransactionalEmailsApi(sib_api_v3_sdk.ApiClient(configuration))
18
+
19
+ def send(self, template_name: str, params: dict, sender_info: dict = None, tags: list = None):
20
+ sender = sender_info if sender_info else SENDER
21
+ send_smtp_email = sib_api_v3_sdk.SendSmtpEmail(
22
+ to=[{"email": params['email']}],
23
+ template_id=int(template_name),
24
+ params=params,
25
+ sender=sender,
26
+ tags=tags
27
+ )
28
+ try:
29
+ self.api_instance.send_transac_email(send_smtp_email)
30
+ return True
31
+ except ApiException as e:
32
+ print("Exception when calling SMTPApi->send_transac_email: %s\n" % e)
33
+ self.logger.error(f'An exception occurred: {e}')
34
+ self.logger.error(e)
35
+ self._notify_slack(f'```An ApiException occurred when sending email: {e}```')
36
+ except Exception as error:
37
+ self.logger.error(error)
38
+ self._notify_slack(f'```An Exception occurred when sending email: {error}```')
39
+ return False
40
+
41
+ def _notify_slack(self, message):
42
+ if self._slack_email_error_url:
43
+ requests.post(self._slack_email_error_url, json={'text': message}, timeout=5)
44
+
45
+ # if __name__ == '__main__':
46
+ # s = SendInBlueClient('CODE', '')
47
+ # s.send(1, {"CODE": "123123", "subject": "Your code", "email": "shay.te@gmail.com"})
@@ -0,0 +1,16 @@
1
+ # @package _global_
2
+ core_lib:
3
+ email_core_lib:
4
+ amqp:
5
+ url:
6
+ protocol: amqp
7
+ username: ${oc.env:AMQP_USERNAME}
8
+ password: ${oc.env:AMQP_PASSWORD}
9
+ host: ${oc.env:AMQP_HOST}
10
+ port: ${oc.env:AMQP_PORT}
11
+ client:
12
+ # _target_: email_core_lib.client.mailchimp_client.MailChimpClient
13
+ # api_key: ${oc.env:EMIL_CORE_LIB_MAILCHIMP_API_KEY}
14
+ _target_: email_core_lib.client.send_in_blue_client.SendInBlueClient
15
+ api_key: ${oc.env:EMIL_CORE_LIB_SEND_IN_BLUE_API_KEY}
16
+ slack_email_error_url: ${oc.env:SLACK_WEBHOOK_URL_ERRORS_EMAIL}
@@ -0,0 +1,17 @@
1
+ import logging
2
+
3
+ from omegaconf import DictConfig
4
+ from core_lib.core_lib import CoreLib
5
+ from core_lib.helpers.config_instances import instantiate_config
6
+
7
+
8
+ class EmailCoreLib(CoreLib):
9
+ def __init__(self, conf: DictConfig):
10
+ super().__init__()
11
+ self.logger = logging.getLogger(self.__class__.__name__)
12
+ self.config = conf
13
+ self.mail_client = instantiate_config(self.config.core_lib.email_core_lib.client)
14
+
15
+ def send(self, template_id, params, sender_info, tags):
16
+ self.logger.info(f'send email. template_id: {template_id}, params: {params}, sender_info: {sender_info}, tags: {tags}')
17
+ self.mail_client.send(template_id, params, sender_info, tags)
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: email_core_lib
3
+ Version: 0.0.0.1
4
+ Summary: Email Core Lib
5
+ Home-page: https://github.com/shay-te/email-core-lib/
6
+ Author: Shay Tessler
7
+ Author-email: shay.te@gmail.com
8
+ License: MIT
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Programming Language :: Python :: 3.7
11
+ Classifier: Topic :: Software Development
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE_2022_4_19
15
+ Requires-Dist: eventlet
16
+ Requires-Dist: mailchimp-transactional
17
+ Requires-Dist: sib-api-v3-sdk
18
+ Dynamic: author
19
+ Dynamic: author-email
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: license
25
+ Dynamic: license-file
26
+ Dynamic: requires-dist
27
+ Dynamic: requires-python
28
+ Dynamic: summary
29
+
30
+ # EmailCoreLib
31
+ `EmailCoreLib` uses [Celery](https://docs.celeryq.dev/en/stable/getting-started/introduction.html) and [MailChimp](https://mailchimp.com/) to receive data and send emails.
32
+ It uses `Celery` to listen to a queue and receive data over it, and `MailChimp` is used to fire emails using their [Transactional Email](https://mailchimp.com/features/transactional-email/) service.
33
+
34
+ ## Services
35
+ - Send Emails using MailChimp
36
+ - Starts Celery Worker to handle requests
37
+
38
+ ## Config
39
+ ```yaml
40
+ core_lib:
41
+ email_core_lib:
42
+ amqp:
43
+ url:
44
+ protocol: amqp
45
+ username: ${oc.env:AMQP_USERNAME}
46
+ password: ${oc.env:AMQP_PASSWORD}
47
+ host: ${oc.env:AMQP_HOST}
48
+ port: ${oc.env:AMQP_PORT}
49
+ client:
50
+ _target_: email_core_lib.client.mailchimp_client.MailChimpClient
51
+ api_key: your_mailchimp_transactional_api_key
52
+ ```
53
+
54
+ ## celery_main.py
55
+ This is the main file that will start the `Celery` worker and initialize the `EmailCoreLib`. As soon as a task is
56
+ dispatched for `task.send` it will use the `MailchimpTransactional` client to send the email.
57
+
58
+ ## EmailCoreLib
59
+ ```python
60
+ class EmailCoreLib(CoreLib):
61
+ def __init__(self, conf: DictConfig):
62
+ super().__init__()
63
+ self.config = conf
64
+ self.mailchimp = instantiate_config(self.config.core_lib.email_core_lib.client)
65
+ ```
66
+ Uses `CoreLib`'s `instantiate_config` that will instantiate the `MailChimpClient` from the config yaml.
67
+
68
+ ## MailChimp Client
69
+ This client will be initialized as soon as the `Celery` worker has started and the `EmailCoreLib` is initialized
70
+
71
+ ### Functions
72
+ ```python
73
+ def send(self, template_name: str, params: dict):
74
+ ```
75
+
76
+ `template_name` (*str*): Name of the saved template in your MailChimp Transactional account
77
+
78
+ `params` (*dict*): A `dict` of variables as keys and their values that are saved in the template to be replaced.
79
+
80
+ ## Example
81
+ ```python
82
+ import hydra
83
+ from celery import Celery
84
+
85
+ hydra.initialize(config_path='config_path', caller_stack_depth=1)
86
+ cfg = hydra.compose('config.yaml')
87
+
88
+ app = Celery()
89
+ app.config_from_object(cfg.core_lib.email_core_lib.amqp.url)
90
+ app.autodiscover_tasks()
91
+
92
+ app.send_task('task.send',
93
+ ['register_complete', {'email': 'john@example.com', 'plan': 'some plan'}]
94
+ )
95
+ ```
96
+ ## License
97
+ Licenced under [MIT](https://github.com/shay-te/email-core-lib/blob/master/LICENSE_2022_4_19)
@@ -0,0 +1,22 @@
1
+ LICENSE_2022_4_19
2
+ MANIFEST.in
3
+ README.md
4
+ requirements.txt
5
+ setup.py
6
+ email_core_lib/__init__.py
7
+ email_core_lib/email_core_lib.py
8
+ email_core_lib.egg-info/PKG-INFO
9
+ email_core_lib.egg-info/SOURCES.txt
10
+ email_core_lib.egg-info/dependency_links.txt
11
+ email_core_lib.egg-info/requires.txt
12
+ email_core_lib.egg-info/top_level.txt
13
+ email_core_lib/client/__init__.py
14
+ email_core_lib/client/mailchimp_client.py
15
+ email_core_lib/client/send_in_blue_client.py
16
+ email_core_lib/config/__init__.py
17
+ email_core_lib/config/email_core_lib.yaml
18
+ hydra_plugins/email_core_lib/__init__.py
19
+ hydra_plugins/email_core_lib/email_core_lib_sourcepath.py
20
+ tests/__init__.py
21
+ tests/test_celery.py
22
+ tests/test_data/__init__.py
@@ -0,0 +1,3 @@
1
+ eventlet
2
+ mailchimp-transactional
3
+ sib-api-v3-sdk
@@ -0,0 +1,3 @@
1
+ email_core_lib
2
+ hydra_plugins
3
+ tests
@@ -0,0 +1,8 @@
1
+ from hydra.plugins.search_path_plugin import SearchPathPlugin
2
+ from hydra.core.config_search_path import ConfigSearchPath
3
+
4
+
5
+ class EmailCoreLibSearchPathPlugin(SearchPathPlugin):
6
+ def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:
7
+ assert isinstance(search_path, ConfigSearchPath)
8
+ search_path.append("email_core_lib", "pkg://email_core_lib.config")
@@ -0,0 +1,5 @@
1
+ celery
2
+ eventlet
3
+ mailchimp-transactional
4
+ sib-api-v3-sdk
5
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,41 @@
1
+ import os
2
+
3
+ import setuptools
4
+
5
+ import email_core_lib
6
+
7
+ from setuptools import find_namespace_packages, setup
8
+ from pip._internal.network.session import PipSession
9
+ from pip._internal.req import parse_requirements
10
+
11
+ dir_path = os.path.dirname(os.path.realpath(__file__))
12
+ install_reqs = parse_requirements(os.path.join(dir_path, 'requirements.txt'), session=PipSession)
13
+ requirements = []
14
+ try:
15
+ requirements = [str(ir.req) for ir in install_reqs]
16
+ except:
17
+ requirements = [str(ir.requirement) for ir in install_reqs]
18
+
19
+ packages1 = setuptools.find_packages()
20
+ packages2 = find_namespace_packages(include=['hydra_plugins.*'])
21
+ packages = list(set(packages1 + packages2))
22
+
23
+ with open('README.md', 'r') as fh:
24
+ long_description = fh.read()
25
+
26
+ setup(
27
+ name='email_core_lib',
28
+ version=email_core_lib.__version__,
29
+ author='Shay Tessler',
30
+ author_email='shay.te@gmail.com',
31
+ description='Email Core Lib',
32
+ long_description=long_description,
33
+ long_description_content_type='text/markdown',
34
+ url='https://github.com/shay-te/email-core-lib/',
35
+ packages=packages,
36
+ license='MIT',
37
+ classifiers=['Development Status :: 4 - Beta', 'Programming Language :: Python :: 3.7', 'Topic :: Software Development'],
38
+ install_requires=requirements,
39
+ include_package_data=True,
40
+ python_requires='>=3.7',
41
+ )
File without changes
@@ -0,0 +1,21 @@
1
+ import os
2
+ import unittest
3
+ import hydra
4
+ from celery import Celery
5
+ from dotenv import load_dotenv
6
+
7
+ from core_lib.data_layers.data.data_helpers import build_url
8
+
9
+ path = os.path.join(os.path.dirname(__file__), 'test_data')
10
+ load_dotenv(dotenv_path=os.path.join(path, '.env'))
11
+ hydra.initialize(config_path='test_data', caller_stack_depth=1)
12
+ cfg = hydra.compose('config.yaml')
13
+
14
+ app = Celery(broker=build_url(**cfg.core_lib.email_core_lib.amqp.url))
15
+ app.autodiscover_tasks()
16
+
17
+
18
+ class Test(unittest.TestCase):
19
+ def test(self):
20
+ app.send_task('task.send',
21
+ ['register_complete', {'email': 'shay@objectivelove.com'}])
File without changes