Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintenance update #69

Merged
merged 6 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.9", "3.8", "3.7"]
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
event-loop: [asyncio, uvloop]

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.9", "3.8", "3.7"]
python-version: ["3.12", "3.11", "3.10", "3.9", "3.8"]
event-loop: [asyncio, uvloop]

steps:
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
Changelog
*********

`8.0.0`_ (2024-08-21)
---------------------

- Add support for Python 3.10/3.11/3.12
- Drop support for Python versions below 3.8
- Bump dependencies
- Add `caption` to file message and to the CLI
- Add an optional parameter to the CLI for `send-simple` and `send-e2e` to allow
passing the text as an argument instead from stdin.
- Make the random padding spec compliant
- Add an optional environment variable `GATEWAY_API_URL` to override the Gateway
API Endpoint URL

`7.0.1`_ (2023-02-21)
---------------------

- Fix parsing of unknown reception capabilities
- Add new `ReceptionCapability` items
Expand Down Expand Up @@ -85,6 +99,7 @@ Server:

- Initial publication on PyPI

.. _8.0.0: https://github.com/threema-ch/threema-msgapi-sdk-python/compare/v7.0.1...v8.0.0
.. _7.0.1: https://github.com/threema-ch/threema-msgapi-sdk-python/compare/v6.0.0...v7.0.1
.. _6.0.0: https://github.com/threema-ch/threema-msgapi-sdk-python/compare/v5.0.0...v6.0.0
.. _5.0.0: https://github.com/threema-ch/threema-msgapi-sdk-python/compare/v4.0.0...v5.0.0
Expand Down
44 changes: 15 additions & 29 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
Threema Gateway API
===================

|Travis| |codecov|

**threema-gateway** is a Python 3 module for the Threema gateway service.
This API can be used to send and receive text messages to and from any Threema
user.
Expand Down Expand Up @@ -69,6 +67,21 @@ the Threema gateway. Run the following command to see usage information:

$ threema-gateway --help

Gateway API Endpoint
--------------------

The default Gateway API Endpoint URL used is https://msgapi.threema.ch/.

If you are a Threema OnPrem customer or have another reason to use a different
Gateway API Endpoint, you may override the URL as follows:

.. code-block:: bash

$ export GATEWAY_API_URL=https://onprem.myinstance.tld/msgapi

Any following calls to ``threema-gateway`` will then use the supplied Gateway
API Endpoint URL.

Examples
********

Expand Down Expand Up @@ -125,34 +138,7 @@ You should also run the type checker that might catch some additional bugs:

$ mypy setup.py tests examples threema

Reporting Security Issues
*************************

Please report security issues directly to one or both of the following
contacts:

- Danilo Bargen

- Email: mail@dbrgn.ch
- Threema: EBEP4UCA
- GPG: `EA456E8BAF0109429583EED83578F667F2F3A5FA`_

- Lennart Grahl

- Email: lennart.grahl@gmail.com
- Threema: MSFVEW6C
- GPG: `3FDB14868A2B36D638F3C495F98FBED10482ABA6`_

.. _asyncio: https://docs.python.org/3/library/asyncio.html
.. _venv: https://docs.python.org/3/library/venv.html
.. _virtualenvwrapper: https://virtualenvwrapper.readthedocs.io/
.. _libsodium: https://download.libsodium.org/doc/installation/index.html

.. |Travis| image:: https://travis-ci.org/threema-ch/threema-msgapi-sdk-python.svg?branch=master
:target: https://travis-ci.org/threema-ch/threema-msgapi-sdk-python
.. |codecov| image:: https://codecov.io/gh/threema-ch/threema-msgapi-sdk-python/branch/master/graph/badge.svg
:target: https://codecov.io/gh/threema-ch/threema-msgapi-sdk-python
.. |PyPI| image:: https://badge.fury.io/py/threema.gateway.svg
:target: https://badge.fury.io/py/threema.gateway
.. _EA456E8BAF0109429583EED83578F667F2F3A5FA: https://keybase.io/dbrgn
.. _3FDB14868A2B36D638F3C495F98FBED10482ABA6: https://keybase.io/lgrahl
3 changes: 2 additions & 1 deletion examples/e2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ async def send_file(connection):
message = FileMessage(
connection=connection,
to_id='ECHOECHO',
file_path='res/some_file.zip'
file_path='res/some_file.zip',
caption="Here's that file I mentioned",
)
return await message.send()

Expand Down
3 changes: 2 additions & 1 deletion examples/e2e_blocking.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ def send_file(connection):
message = FileMessage(
connection=connection,
to_id='ECHOECHO',
file_path='res/some_file.zip'
file_path='res/some_file.zip',
caption="Here's that file I mentioned",
)
return message.send()

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bdist_wheel]
python-tag = py37.py38.py39.py310
python-tag = py38.py39.py310.py311.py312

[flake8]
max-line-length = 90
Expand Down
17 changes: 8 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ def read(file):
# Note: These are just tools that aren't required, so a version range
# is not necessary here.
tests_require = [
'pytest>=7.1.2,<8',
'pytest-asyncio>=0.18.3,<0.19',
'pytest-cov>=3.0.0,<4',
'flake8==4.0.1',
'isort==5.10.1',
'pytest>=8.3.2,<9',
'pytest-asyncio>=0.21.2,<0.23',
'flake8==7.1.1',
'isort==5.13.2',
'collective.checkdocs>=0.2,<0.3',
'Pygments>=2.12.0', # required by checkdocs
'mypy==0.961',
'Pygments>=2.18.0', # required by checkdocs
'mypy==1.11.1',
]

setup(
Expand All @@ -54,7 +53,7 @@ def read(file):
packages=find_packages(include=["threema.*"]),
install_requires=[
'logbook>=1.1.0,<2',
'libnacl>=1.5.2,<2',
'libnacl>=1.5.2,<3',
'click>=8,<9',
'aiohttp>=3.7.3,<4',
'wrapt>=1.10.10,<2',
Expand All @@ -73,7 +72,7 @@ def read(file):

# PyPI metadata
author='Lennart Grahl',
author_email='lennart.grahl@gmail.com',
author_email='lennart.grahl@threema.ch',
description=('An API for the Threema gateway service to send and receive '
'messages including text, images, files and delivery reports.'),
long_description=long_description,
Expand Down
11 changes: 3 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,9 @@ def event_loop(request):
"""
default_event_loop(request=request)

# Close previous event loop
policy = asyncio.get_event_loop_policy()
policy.get_event_loop().close()

# Create new event loop
_event_loop = policy.new_event_loop()
policy.set_event_loop(_event_loop)
_event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(_event_loop)

def fin():
_event_loop.close()
Expand All @@ -383,8 +379,7 @@ async def start_server():
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(
runner, host=pytest.msgapi['msgapi']['ip'], port=port, shutdown_timeout=1.0
)
runner, host=pytest.msgapi['msgapi']['ip'], port=port, shutdown_timeout=1.0)
await site.start()
return app, runner, site
app, runner, site = event_loop.run_until_complete(start_server())
Expand Down
18 changes: 15 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async def test_invalid_key(self, cli):
assert 'Invalid key type' in exc_info.value.output

@pytest.mark.asyncio
async def test_encrypt_decrypt(self, cli):
async def test_encrypt_decrypt_stdin(self, cli):
input = '私はガラスを食べられます。それは私を傷つけません。'
output = await cli(
'encrypt', pytest.msgapi['msgapi']['private'],
Expand All @@ -43,6 +43,18 @@ async def test_encrypt_decrypt(self, cli):
pytest.msgapi['msgapi']['public'], nonce, input=data)
assert input in output

@pytest.mark.asyncio
async def test_encrypt_decrypt_parameter(self, cli):
input = '私はガラスを食べられます。それは私を傷つけません。'
output = await cli(
'encrypt', pytest.msgapi['msgapi']['private'],
pytest.msgapi['msgapi']['public'], input=input)
nonce, data = output.splitlines()
output = await cli(
'decrypt', pytest.msgapi['msgapi']['private'],
pytest.msgapi['msgapi']['public'], nonce, data)
assert input in output

@pytest.mark.asyncio
async def test_encrypt_decrypt_by_file(self, cli, private_key_file, public_key_file):
input = '私はガラスを食べられます。それは私を傷つけません。'
Expand Down Expand Up @@ -155,7 +167,7 @@ async def test_send_file(self, cli, server):
output_1 = await cli(
'send-file', 'ECHOECHO', pytest.msgapi['msgapi']['id'],
pytest.msgapi['msgapi']['secret'], pytest.msgapi['msgapi']['private'],
server.threema_jpg)
server.threema_jpg, '-c', 'See the picture?')
assert output_1
assert len(server.latest_blob_ids) == 1
output_2 = await cli(
Expand Down Expand Up @@ -252,7 +264,7 @@ async def test_invalid_id(self, cli):
@pytest.mark.asyncio
async def test_insufficient_credits(self, cli):
with pytest.raises(subprocess.CalledProcessError) as exc_info:
id_, secret = pytest.msgapi['msgapi']['nocredit_id'],\
id_, secret = pytest.msgapi['msgapi']['nocredit_id'], \
pytest.msgapi['msgapi']['secret']
await cli('send-simple', 'ECHOECHO', id_, secret, input='!')
assert 'Insufficient credits' in exc_info.value.output
4 changes: 2 additions & 2 deletions threema/gateway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

The mode that you can use depends on the way your account was set up.

.. moduleauthor:: Lennart Grahl <lennart.grahl@gmail.com>
.. moduleauthor:: Lennart Grahl <lennart.grahl@threema.ch>
"""
import itertools

Expand All @@ -28,7 +28,7 @@
from ._gateway import * # noqa
from .exception import * # noqa

__author__ = 'Lennart Grahl <lennart.grahl@gmail.com>'
__author__ = 'Lennart Grahl <lennart.grahl@threema.ch>'
__status__ = 'Production'
__version__ = '7.0.1'
feature_level = 3
Expand Down
3 changes: 2 additions & 1 deletion threema/gateway/_gateway.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import enum
import io

import aiohttp
import libnacl.encode
Expand Down Expand Up @@ -293,7 +294,7 @@ async def upload(self, data):

Return the hex-encoded ID of the blob.
"""
return await self._upload(self.urls['upload_blob'], data)
return await self._upload(self.urls['upload_blob'], data=io.BytesIO(data))

async def download(self, blob_id):
"""
Expand Down
Loading
Loading