message-sender 0.1.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.
@@ -0,0 +1,16 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "uv"
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ labels:
8
+ - skip-changelog
9
+ - dependencies
10
+ - package-ecosystem: "github-actions"
11
+ directory: '/'
12
+ schedule:
13
+ interval: daily
14
+ labels:
15
+ - skip-changelog
16
+ - dependencies
@@ -0,0 +1,25 @@
1
+ name-template: 'v$RESOLVED_VERSION'
2
+ tag-template: 'v$RESOLVED_VERSION'
3
+ exclude-labels:
4
+ - 'dependencies'
5
+ - 'skip-changelog'
6
+ version-resolver:
7
+ major:
8
+ labels:
9
+ - 'breaking-change'
10
+ minor:
11
+ labels:
12
+ - 'enhancement'
13
+ default: patch
14
+ categories:
15
+ - title: '⚠ Breaking changes'
16
+ label: 'breaking-change'
17
+ - title: 'Features'
18
+ labels: 'enhancement'
19
+ - title: 'Bug Fixes'
20
+ labels: 'bug'
21
+ change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
22
+ template: |
23
+ ## Changes
24
+
25
+ $CHANGES
@@ -0,0 +1,27 @@
1
+ name: PyPi Publish
2
+ on:
3
+ release:
4
+ types:
5
+ - published
6
+ jobs:
7
+ deploy:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ # For PyPI's trusted publishing.
11
+ id-token: write
12
+ steps:
13
+ - uses: actions/checkout@v6
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v7
16
+ with:
17
+ enable-cache: true
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v6
20
+ with:
21
+ python-version: "3.14"
22
+ - name: Install Dependencies
23
+ run: uv sync --frozen
24
+ - name: Build package
25
+ run: uv build
26
+ - name: Publish package
27
+ run: uv publish
@@ -0,0 +1,16 @@
1
+ name: Release Drafter
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ update_release_draft:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: release-drafter/release-drafter@v6
13
+ with:
14
+ config-name: release_drafter_template.yml
15
+ env:
16
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,57 @@
1
+ name: Testing
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+ env:
9
+ UV_CACHE_DIR: /tmp/.uv-cache
10
+ PYTHON_VERSION: "3.11"
11
+ jobs:
12
+ linting:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v7
18
+ with:
19
+ enable-cache: true
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v6
22
+ with:
23
+ python-version: ${{ env.PYTHON_VERSION }}
24
+ - name: Install Dependencies
25
+ run: uv sync --frozen
26
+ - name: Ruff format check
27
+ run: uv run ruff format message_sender tests --check
28
+ - name: Lint with ruff
29
+ run: uv run ruff check .
30
+ - name: mypy check
31
+ run: uv run mypy .
32
+ testing:
33
+ strategy:
34
+ fail-fast: false
35
+ matrix:
36
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
37
+ os: [ubuntu-latest, windows-latest, macos-latest]
38
+ runs-on: ${{ matrix.os }}
39
+ steps:
40
+ - uses: actions/checkout@v6
41
+ - name: Install uv
42
+ uses: astral-sh/setup-uv@v7
43
+ with:
44
+ enable-cache: true
45
+ - name: Set up Python ${{ matrix.python-version }}
46
+ uses: actions/setup-python@v6
47
+ with:
48
+ python-version: ${{ matrix.python-version }}
49
+ - name: Install Dependencies
50
+ run: uv sync --frozen
51
+ - name: Test with pytest
52
+ run: uv run pytest --cov-report=xml
53
+ - name: Upload coverage
54
+ uses: codecov/codecov-action@v5.5.2
55
+ with:
56
+ token: ${{ secrets.CODECOV_TOKEN }}
57
+ fail_ci_if_error: true
@@ -0,0 +1,138 @@
1
+
2
+ # Byte-compiled / optimized / DLL files
3
+ __pycache__/
4
+ *.py[cod]
5
+ *$py.class
6
+
7
+ # OS Files
8
+ *.swp
9
+ *.DS_Store
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ pip-wheel-metadata/
29
+ share/python-wheels/
30
+ *.egg-info/
31
+ .installed.cfg
32
+ *.egg
33
+ MANIFEST
34
+
35
+ # PyInstaller
36
+ # Usually these files are written by a python script from a template
37
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ target/
81
+
82
+ # Jupyter Notebook
83
+ .ipynb_checkpoints
84
+
85
+ # IPython
86
+ profile_default/
87
+ ipython_config.py
88
+
89
+ # pyenv
90
+ .python-version
91
+
92
+ # pipenv
93
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
95
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
96
+ # install all needed dependencies.
97
+ #Pipfile.lock
98
+
99
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
100
+ __pypackages__/
101
+
102
+ # Celery stuff
103
+ celerybeat-schedule
104
+ celerybeat.pid
105
+
106
+ # SageMath parsed files
107
+ *.sage.py
108
+
109
+ # Environments
110
+ .env
111
+ .venv
112
+ env/
113
+ venv/
114
+ ENV/
115
+ env.bak/
116
+ venv.bak/
117
+
118
+ # Spyder project settings
119
+ .spyderproject
120
+ .spyproject
121
+
122
+ # Rope project settings
123
+ .ropeproject
124
+
125
+ # mkdocs documentation
126
+ /site
127
+
128
+ # mypy
129
+ .mypy_cache/
130
+ .dmypy.json
131
+ dmypy.json
132
+
133
+ # Pyre type checker
134
+ .pyre/
135
+
136
+ # editors
137
+ .idea
138
+ .vscode
@@ -0,0 +1,21 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v6.0.0
4
+ hooks:
5
+ - id: check-added-large-files
6
+ - id: check-toml
7
+ - id: check-yaml
8
+ - id: debug-statements
9
+ - id: end-of-file-fixer
10
+ - id: trailing-whitespace
11
+ - id: no-commit-to-branch
12
+ - repo: https://github.com/pre-commit/mirrors-mypy
13
+ rev: v1.19.1
14
+ hooks:
15
+ - id: mypy
16
+ - repo: https://github.com/astral-sh/ruff-pre-commit
17
+ rev: v0.14.13
18
+ hooks:
19
+ - id: ruff-check
20
+ args: [--fix, --exit-non-zero-on-fix]
21
+ - id: ruff-format
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Paul Sanders
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.
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: message-sender
3
+ Version: 0.1.0
4
+ Summary: Sends Messages with different services such as email
5
+ Author-email: Paul Sanders <paul@paulsanders.dev>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Paul Sanders
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ License-File: LICENSE
28
+ Requires-Python: >=3.11
29
+ Requires-Dist: aiosmtplib>=5.0.0
30
+ Requires-Dist: httpx>=0.28.1
31
+ Description-Content-Type: text/markdown
32
+
33
+ # Message Sender
34
+
35
+ [![Tests Status](https://github.com/sanders41/message-sender/actions/workflows/testing.yml/badge.svg?branch=main&event=push)](https://github.com/sanders41/message-sender/actions?query=workflow%3ATesting+branch%3Amain+event%3Apush)
36
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sanders41/message-sender/main.svg)](https://results.pre-commit.ci/latest/github/sanders41/message-sender/main)
37
+ [![Coverage](https://codecov.io/github/sanders41/message-sender/coverage.svg?branch=main)](https://codecov.io/gh/sanders41/message-sender)
38
+ [![PyPI version](https://badge.fury.io/py/message-sender.svg)](https://badge.fury.io/py/message-sender)
39
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/message-sender?color=5cc141)](https://github.com/sanders41/message-sender)
40
+
41
+ Sends messages with different services such as email and Google Chat.
42
+
43
+ ## Installation
44
+
45
+ ```sh
46
+ pip install message-sender
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ ### Google Chat
52
+
53
+ Send messages to Google Chat via webhooks. To set this up, create a "space" in Google Chat, then go
54
+ to Apps & integrations and create a new webhook.
55
+
56
+ #### Sync Client
57
+
58
+ ```py
59
+ from message_sender.google_chat import GoogleChatClient
60
+
61
+ with GoogleChatClient("https://your-webhook-url.com") as client:
62
+ client.send_message("Some test message")
63
+ ```
64
+
65
+ #### Async Client
66
+
67
+ ```py
68
+ from message_sender.google_chat import AsyncGoogleChatClient
69
+
70
+ async with AsyncGoogleChatClient("https://your-webhook-url.com") as client:
71
+ await client.send_message("Some test message")
72
+ ```
73
+
74
+ ### Proton Email
75
+
76
+ Send emails through Proton Mail's SMTP service. For setup instructions see
77
+ [https://proton.me/support/smtp-submission](https://proton.me/support/smtp-submission)
78
+
79
+ #### Sync Client
80
+
81
+ ```py
82
+ from message_sender.email.proton import ProtonEmailClient
83
+
84
+ client = ProtonEmailClient(
85
+ email_address="smtp_setup_email@proton.me", smtp_token="your-token"
86
+ )
87
+ client.send_email(
88
+ message="Your message body",
89
+ email_to="someone@email.com",
90
+ subject="Example",
91
+ html_content="<p>Your HTML message body</p>", # optional
92
+ )
93
+ ```
94
+
95
+ #### Async Client
96
+
97
+ ```py
98
+ from message_sender.email.proton import AsyncProtonEmailClient
99
+
100
+ client = AsyncProtonEmailClient(
101
+ email_address="smtp_setup_email@proton.me", smtp_token="your-token"
102
+ )
103
+ await client.send_email(
104
+ message="Your message body",
105
+ email_to="someone@email.com",
106
+ subject="Example",
107
+ html_content="<p>Your HTML message body</p>", # optional
108
+ )
109
+ ```
@@ -0,0 +1,77 @@
1
+ # Message Sender
2
+
3
+ [![Tests Status](https://github.com/sanders41/message-sender/actions/workflows/testing.yml/badge.svg?branch=main&event=push)](https://github.com/sanders41/message-sender/actions?query=workflow%3ATesting+branch%3Amain+event%3Apush)
4
+ [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sanders41/message-sender/main.svg)](https://results.pre-commit.ci/latest/github/sanders41/message-sender/main)
5
+ [![Coverage](https://codecov.io/github/sanders41/message-sender/coverage.svg?branch=main)](https://codecov.io/gh/sanders41/message-sender)
6
+ [![PyPI version](https://badge.fury.io/py/message-sender.svg)](https://badge.fury.io/py/message-sender)
7
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/message-sender?color=5cc141)](https://github.com/sanders41/message-sender)
8
+
9
+ Sends messages with different services such as email and Google Chat.
10
+
11
+ ## Installation
12
+
13
+ ```sh
14
+ pip install message-sender
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Google Chat
20
+
21
+ Send messages to Google Chat via webhooks. To set this up, create a "space" in Google Chat, then go
22
+ to Apps & integrations and create a new webhook.
23
+
24
+ #### Sync Client
25
+
26
+ ```py
27
+ from message_sender.google_chat import GoogleChatClient
28
+
29
+ with GoogleChatClient("https://your-webhook-url.com") as client:
30
+ client.send_message("Some test message")
31
+ ```
32
+
33
+ #### Async Client
34
+
35
+ ```py
36
+ from message_sender.google_chat import AsyncGoogleChatClient
37
+
38
+ async with AsyncGoogleChatClient("https://your-webhook-url.com") as client:
39
+ await client.send_message("Some test message")
40
+ ```
41
+
42
+ ### Proton Email
43
+
44
+ Send emails through Proton Mail's SMTP service. For setup instructions see
45
+ [https://proton.me/support/smtp-submission](https://proton.me/support/smtp-submission)
46
+
47
+ #### Sync Client
48
+
49
+ ```py
50
+ from message_sender.email.proton import ProtonEmailClient
51
+
52
+ client = ProtonEmailClient(
53
+ email_address="smtp_setup_email@proton.me", smtp_token="your-token"
54
+ )
55
+ client.send_email(
56
+ message="Your message body",
57
+ email_to="someone@email.com",
58
+ subject="Example",
59
+ html_content="<p>Your HTML message body</p>", # optional
60
+ )
61
+ ```
62
+
63
+ #### Async Client
64
+
65
+ ```py
66
+ from message_sender.email.proton import AsyncProtonEmailClient
67
+
68
+ client = AsyncProtonEmailClient(
69
+ email_address="smtp_setup_email@proton.me", smtp_token="your-token"
70
+ )
71
+ await client.send_email(
72
+ message="Your message body",
73
+ email_to="someone@email.com",
74
+ subject="Example",
75
+ html_content="<p>Your HTML message body</p>", # optional
76
+ )
77
+ ```
@@ -0,0 +1,31 @@
1
+ @_default:
2
+ just --list
3
+
4
+ @lint:
5
+ echo mypy
6
+ just --justfile {{justfile()}} mypy
7
+ echo ruff-check
8
+ just --justfile {{justfile()}} ruff-check
9
+ echo ruff-format
10
+ just --justfile {{justfile()}} ruff-format
11
+
12
+ @mypy:
13
+ uv run mypy message_sender tests
14
+
15
+ @ruff-check:
16
+ uv run ruff check message_sender tests
17
+
18
+ @ruff-format:
19
+ uv run ruff format message_sender tests
20
+
21
+ @lock:
22
+ uv lock
23
+
24
+ @lock-upgrade:
25
+ uv lock --upgrade
26
+
27
+ @install:
28
+ uv sync --frozen --all-extras
29
+
30
+ @test *args="":
31
+ uv run pytest {{args}}
@@ -0,0 +1,3 @@
1
+ from message_sender._version import VERSION
2
+
3
+ __version__ = VERSION
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ VERSION = "0.1.0"
File without changes