Python client library for Postmark API

Overview

Postmarker

Build Coverage Version Python versions Documentation Status Gitter License

Python client library for Postmark API.

Gitter: https://gitter.im/Stranger6667/postmarker

Installation

Postmarker can be obtained with pip:

$ pip install postmarker

Usage example

NOTE:

The attributes of all classes are provided as is, without transformation to snake case. We don't want to introduce new names for existing entities.

Send single email:

>>> from postmarker.core import PostmarkClient
>>> postmark = PostmarkClient(server_token='API_TOKEN')
>>> postmark.emails.send(
    From='[email protected]',
    To='[email protected]',
    Subject='Postmark test',
    HtmlBody='Hello dear Postmark user.'
)

Send batch:

>>> postmark.emails.send_batch(
    {
        'From': '[email protected]',
        'To': '[email protected]',
        'Subject': 'Postmark test',
        'HtmlBody': 'Hello dear Postmark user.',
    },
    {
        'From': '[email protected]',
        'To': '[email protected]',
        'Subject': 'Postmark test 2',
        'HtmlBody': 'Hello dear Postmark user.',
    }
)

Setup an email:

>>> email = postmark.emails.Email(
    From='[email protected]',
    To='[email protected]',
    Subject='Postmark test',
    HtmlBody='Hello dear Postmark user.'
)
>>> email['X-Accept-Language'] = 'en-us, en'
>>> email.attach('/home/user/readme.txt')
>>> email.attach_binary(content=b'content', filename='readme.txt')
>>> email.send()

There are a lot of features available. Check it out in our documentation! Here's just a few of them:

  • Support for sending Python email instances.
  • Bounces, Domains, Messages, Templates, Sender signatures, Status, Stats & Server API.
  • Django email backend.
  • Tornado helper.
  • Spam check API.
  • Wrappers for Bounce, Inbound, Open and Delivery webhooks.

Documentation

You can view the documentation online at:

Or you can look at the docs/ directory in the repository.

Python support

Postmarker supports Python 3.6 - 3.9 and PyPy3.

Thanks

Many thanks to Shmele and lobziik for their reviews and advices :)

Comments
  • TypeError for SafeMIMEText

    TypeError for SafeMIMEText

    Follow up for this comment:

    @Stranger6667 Is this working for you? I am getting the same exception with Python 2.7, Django 1.11 as well as Python 3.6, Django 1.11.

    I get

    TypeError: Object of type 'SafeMIMEText' is not JSON serializable and I am unable to debug the issue.

    Hi @suriya ! Could you, please, add some code to reproduce the issue?

    opened by Stranger6667 9
  • Send Tag information via the Django interface

    Send Tag information via the Django interface

    I can't figure out a way to send Tag information to Postmark when using the Django EmailBackend. I did dive deep into the code but unfortunately had difficulty figuring out where the right place even to patch it would be.

    I know I could use the regular PostmarkClient, but it's important for us to continue using the built-in Django mechanism so that we can stay vendor agnostic.

    Can you point me in the right direction on where a patch would go?

    opened by jdotjdot 8
  • Remove dependency on mock

    Remove dependency on mock

    Postmarker has a dependency on mock, used here: https://github.com/Stranger6667/postmarker/blob/c0c0f7af623dc7b3fc0c030867773755dca31f67/postmarker/_compat.py#L13

    I notice that mock.patch is used only in tests. Does this make sense to move the line to a separate file _compat_tests.py so that normal usage of postmarker does not need the mock package?

    opened by suriya 7
  • Action required: Upcoming TLS configuration changes

    Action required: Upcoming TLS configuration changes

    Thank you so much for your work here!

    Just wanted to confirm if this package will be affected by the Postmark upcoming TLS configuration changes?

    The email below was received just a few hours ago:

    Hi there, To ensure the continued security of our systems, we wanted to let you know about some upcoming changes to our TLS (Transport Layer Security) configurations for API access.These changes may affect your application’s ability to continue to send mail through Postmark, so please read through this email in detail. You can also read through these changes on our website.These changes do not affect sending via SMTP.

    What’s changingOn April 13, 2021, we are going to (1) disable TLSv1 access, (2) disable all RC4 and low-strength ciphers, and (3) add HSTS headers.Here’s the full timeline of the changes:February 2021: Announcement of the changes, and testing endpoints are made available.March 23, 2021: Perform “blackout” test, where we cut over to the new configuration for one hour in production.March 30, 2021: Perform another “blackout” test, where we cut over to the new configuration for 12 hours in production.April 13, 2021: Cut over production to new configuration permanently.April 20, 2021: Decommission temporary testing SSL endpoint.We’ll discuss each change below, as well as your next steps to make sure sending isn’t interrupted. Changes and impact(1) Disabling TLSv1 accessTLSv1 has been deprecated, and we are following suit.Impact: Connections that only support TLSv1 would not be able to connect anymore after this change.(2) Disabling all RC4 and low-strength ciphersRC4 ciphers are considered weak and they are deprecated as well. Along with this, we are getting rid of any low-strength ciphers that are vulnerable to breaks as well.Impact: Connections that only support these old/weak ciphers would not be able to connect anymore after this change.(3) Adding HSTS headersHSTS (HTTP Strict Transport Security) headers tell web clients to only ever connect to a URL over HTTPS for a period of time (usually 6 months to 1 year). This prevents something called a “downgrade attack”, where users are tricked into visiting a version of a URL that is not secured or validated with TLS.Impact: We are adding these headers in accordance with industry standards. There is no API connectivity impact. ----- | -----

    What you need to doIf you send with Postmark via our API, please make sure that your sending infrastructure is able to deal with these changes prior to the April 13 cutover date.We’ve set up a temporary endpoint at api-ssl-temp.postmarkapp.com that has these changes already applied. You can use this as an endpoint to test/validate against. Please be aware that there is no expectation of uptime on this endpoint, and that it will be shut down on April 20, 2021 with no further notice. It should only be used for temporary testing of non-production traffic.If any of your tests with the temporary endpoint fail, updating your OpenSSL library should resolve the issue. If you are having trouble getting your API integration to work with this temporary endpoint, please contact our support team and let us know the exact error message encountered when attempting to connect, and a log of the connection attempt. We may be able to provide specific instructions for using newer TLS configurations.If you have any questions, just reply to this email. We’re here to help!

    opened by v-ken 5
  • Documentation is outdated on ReadTheDocs

    Documentation is outdated on ReadTheDocs

    Unfortunately the docs at https://postmarker.readthedocs.io/en/stable/ are stuck on 1.3.0.

    Looking at the changes since then (see https://github.com/Stranger6667/postmarker/compare/0.13.0...v0.17.1), I'm not too sure what could have caused this, but I know RTD to be quite picky about docs dependencies, so maybe the move to pyproject.toml?

    opened by loicteixeira 4
  • send_with_template won't allow alias

    send_with_template won't allow alias

    Referring to #150

    When I try to send an email using a template alias, postmark.emails.send_with_template(TemplateAlias=alias, TemplateModel=model, To=sendto, From=efrom)

    I get the following response: TypeError: send_with_template() missing 1 required positional argument: 'TemplateId'

    Thanks.

    opened by 2x2xplz 4
  • Django backend crashes when sending a message with attachments

    Django backend crashes when sending a message with attachments

    Postmarker's Django backend crashes when sending a message with attachments. The crash happens when therequests library tries to convert a dictionary containing email message information into a JSON string. The conversion fails for attachments.

    Here's a stack trace.

      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/django/core/mail/message.py", line 303, in send
        return self.get_connection(fail_silently).send_messages([self])
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/django.py", line 57, in send_messages
        response = self.client.emails.send_batch(*prepared_messages, TrackOpens=self.get_option('TRACK_OPENS'))
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/models/emails.py", line 324, in send_batch
        return self.EmailBatch(*emails).send(**extra)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/models/emails.py", line 245, in send
        responses = [self._manager._send_batch(*batch) for batch in chunks(emails, self.MAX_SIZE)]
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/models/emails.py", line 268, in _send_batch
        return self.call('POST', '/email/batch', data=emails)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/models/base.py", line 63, in call
        return self.client.call(*args, **kwargs)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/core.py", line 84, in call
        **kwargs
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/postmarker/core.py", line 106, in _call
        response = self.session.request(method, url, json=data, params=kwargs, headers=default_headers)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/requests/sessions.py", line 474, in request
        prep = self.prepare_request(req)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/requests/sessions.py", line 407, in prepare_request
        hooks=merge_hooks(request.hooks, self.hooks),
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/requests/models.py", line 305, in prepare
        self.prepare_body(data, files, json)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/requests/models.py", line 462, in prepare_body
        body = complexjson.dumps(json)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/simplejson/__init__.py", line 280, in dumps
        def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/simplejson/encoder.py", line 291, in encode
        chunks = self.iterencode(o, _one_shot=True)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/simplejson/encoder.py", line 373, in iterencode
        return _iterencode(o, 0)
      File "/home/vagrant/bookshelf.git/my-env/local/lib/python2.7/site-packages/simplejson/encoder.py", line 268, in default
        raise TypeError(repr(o) + " is not JSON serializable")
    TypeError: <django.core.mail.message.SafeMIMEText instance at 0x7f15eacc8e18> is not JSON serializable
    
    opened by suriya 4
  • Unable to handle Unicode in message body using API

    Unable to handle Unicode in message body using API

    Sorry to be leaving you so many issues!

    Looks like there's now an issue when sending messages at least with unicode characters in the body. The message I am sending usings django.template.Template to render a template to a string and then submit it as the message HTML body.

    This problem goes away if you temporarily set sys.setdefaultencoding('utf8') (which you obviously shouldn't be doing).

    Here is the traceback:

    /Users/../utils/emails.pyc in send_html_email(subject, from_email, to_emails, reply_to, text_body, html_body, headers, tag, metadata, subaccount, attachments, send_in, extra_params, bcc)
        128             setattr(msg, key, value)
        129
    --> 130     msg.send()
        131
        132
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/django/core/mail/message.pyc in send(self, fail_silently)
        340             # send to.
        341             return 0
    --> 342         return self.get_connection(fail_silently).send_messages([self])
        343
        344     def attach(self, filename=None, content=None, mimetype=None):
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/django.pyc in send_messages(self, email_messages)
         55             client_created = self.open()
         56             prepared_messages = [self.prepare_message(message) for message in email_messages]
    ---> 57             response = self.client.emails.send_batch(*prepared_messages, TrackOpens=self.get_option('TRACK_OPENS'))
         58             msg_count = len(response)
         59             if client_created:
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in send_batch(self, *emails, **extra)
        322         :param extra: dictionary with extra arguments for every message in the batch.
        323         """
    --> 324         return self.EmailBatch(*emails).send(**extra)
        325
        326     # NOTE. The following methods are included here to expose better interface without need to import relevant classes.
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in send(self, **extra)
        242         :rtype: `list`
        243         """
    --> 244         emails = self.as_dict(**extra)
        245         responses = [self._manager._send_batch(*batch) for batch in chunks(emails, self.MAX_SIZE)]
        246         return sum(responses, [])
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in as_dict(self, **extra)
        220         :return: List of dictionaries.
        221         """
    --> 222         return [self._construct_email(email, **extra) for email in self.emails]
        223
        224     def _construct_email(self, email, **extra):
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in _construct_email(self, email, **extra)
        229             email = Email(manager=self._manager, **email)
        230         elif isinstance(email, (MIMEText, MIMEMultipart)):
    --> 231             email = Email.from_mime(email, self._manager)
        232         elif not isinstance(email, Email):
        233             raise ValueError
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in from_mime(cls, message, manager)
        178         """
        179         if isinstance(message, MIMEMultipart):
    --> 180             text, html, attachments = deconstruct_multipart(message)
        181         else:
        182             text, html, attachments = message.get_payload(decode=True).decode(), None, []
    
    /Users/../.virtualenvs/TCJ/lib/python2.7/site-packages/postmarker/models/emails.pyc in deconstruct_multipart(message)
         85             text = part.get_payload(decode=True).decode()
         86         elif content_type == 'text/html':
    ---> 87             html = part.get_payload(decode=True).decode()
         88         elif content_type != 'multipart/alternative':
         89             attachments.append(part)
    
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 3495: ordinal not in range(128)
    

    I'm currently getting around this with the following context manager, but obviously this cannot be the case long-term:

    @contextlib.contextmanager
    def set_default_encoding(encoding='ascii'):
        """\
        Temporarily set the default encoding within the span of the context.
    
        NOTE: Using `sys.setdefaultencoding()` is HIGHLY DISCOURAGED and this context
        manager should only be used when working with third party libraries that incorrectly
        handle unicode/strings/bytestrings and cannot easily be patched, updated, or worked around.
        """
        import sys
        reload(sys)
        original_encoding = sys.getdefaultencoding()
        sys.setdefaultencoding(encoding)
        yield
        sys.setdefaultencoding(original_encoding)
    
    opened by jdotjdot 4
  • Library incorrectly quotes long lines when sent via API

    Library incorrectly quotes long lines when sent via API

    If large HTML files (particularly those with large lines, for example anything produced using MJML with the --min minification flag enabled) are sent using Postmarker, the HTML is escaped using quoted-printable and sent to Postmark's API that way, when it should actually be sent unquoted.

    The reason this happens is under the hood, Postmarker calls the Django email backend's message.message() within EmailBackend.prepare_message(). This has the message turn itself into MIME, which then is later deconstructed back to a dict using Email.from_mime(). Since Django thinks it's serializing the email for an SMTP send, it automatically quotes the email or alternative attachment under certain circumstances (utf-8 + long lines, see django.core.mail.message.py:220) and sets the Content-Transfer-Encoding to quoted-printable. When Postmarker turns that back into a dict, it loses the Content-Transfer-Encoding header and does not unquote, leading to the quoted version being sent directly via Postmark's API and completely incorrect emails being sent, particularly if they include any Outlook-specific markup that uses XML namespaces and colons.

    One way to fix this is when converting the MIME email back to a dictionary, to detect if it has been quoted and then to unquote using email.quoprimime.body_decode(...). Alternatively, the better way to fix this is to refactor simply not to let Django's mailing backend create the MIME email at all, and simply send the body and headers to Postmark via the API without doing any unnecessary processing. This is how djrill for Mandrill works, and emails I sent with Postmarker that got mangled were not mangled with djrill.

    opened by jdotjdot 4
  • Django 4.0 incompatibilities

    Django 4.0 incompatibilities

    Django release 4.0 has introduced some incompatibilities but they are all quite benign.

    1. django/utils/encoding#force_text has been removed. It was previously deprecated.

    force_str can be used as a direct replacement and was aliased. Available since Feb 2019 https://github.com/django/django/commit/3bb6a4390c0a57da991fcb1c0642b9b3fccff751

    force_text was deprecated shortly after in https://github.com/django/django/commit/d55e88292723764a16f0689c73bc7e739dfa6047

    force_text was then removed in the v4 release cycle as per the deprecation notice https://github.com/django/django/commit/810f037b29402f848a766f6900b4ebfbaf64cc88

    1. Signal has lost the provided_args initialiser argument

    This argument was deprecated in Mar 2020 at https://github.com/django/django/commit/769cee525222bb155735aba31d6174d73c271f3c

    And subsequently removed in Jan 2021 at https://github.com/django/django/commit/1adcf20385c2856d3655089ff7a0b55b32e5587a

    I don't know which previous versions of Django this affects or how backwards compatible you want to be, but I'll post a RP with these changes to run through Django v4.0

    opened by robshep 3
  • Update domains verification methods

    Update domains verification methods

    Postmark deprecated verifyspf (see https://postmarkapp.com/blog/why-we-no-longer-ask-for-spf-records).

    This PR:

    • Updates the test case for verifyspf to reflect this (ie. SPFVerified is always True)
    • Introduces 2 new methods for verifyDkim and verifyReturnPath API endpoints
    opened by n11c 3
  • fix: expose `on_exception` with other Django signals

    fix: expose `on_exception` with other Django signals

    on_exception is missing from src/postmarker/django/__init__.py, making it impossible to do

    from postmarker.django import on_exception
    

    even though the pre_send and post_send signals are exposed in this way.

    Thanks

    opened by gregsadetsky 0
  • Suggestion: better documentation of `emails` parameter for send_batch and send_template_batch

    Suggestion: better documentation of `emails` parameter for send_batch and send_template_batch

    The documentation for send_batch and send_template_batch both mention:

    Parameters emails – Email instances or dictionaries

    However, emails is actually equivalent to *args, i.e. emails internally captures (within send_batch and send_template_batch) all arguments passed to the function. The variable name emails is not actually exposed to the caller, and so isn't properly a "parameter".

    Calling:

    postmark.emails.send_batch(emails=[email, another_email])
    

    will not work -- the function will instead confusingly return an empty array.

    Just in case anybody comes here to troubleshoot this, the correct way to call the functon is rather:

    postmark.emails.send_batch(email, another_email)
    # ... or alternatively ...
    my_emails = [email, another_email]
    postmark.emails.send_batch(*my_emails)
    

    Thanks!

    opened by gregsadetsky 1
  • Suggestion: better string representation of Email object

    Suggestion: better string representation of Email object

    After creating an Email object, converting it to a string representation leads to a confusing output.

    Example:

    e = postmark_client.emails.Email(From="[email protected]", To="[email protected]", TextBody="text")
    print(e)
    

    This outputs <Email: None>

    Cheers

    opened by gregsadetsky 0
  • Offset / count invariant when you have more than 10,000 messages

    Offset / count invariant when you have more than 10,000 messages

    Hi there,

    Thanks for a great library. I'm running into an edge case. If you have more than 10,000 outbound messages, this library will break as the count=None loop will eventually send a request like so:

    https://api.postmarkapp.com/messages/outbound?count=500&offset=10000

    And per Postmark's docs, the max of count + offset = 10,000.

    So you'll get a 500 error from them.

    This isn't an issue if the TotalCount in base.py returns less 10,000 because you'll break out of the loop.

    I'm not sure how best to handle this. It seems like, no matter what we do, we can't get to message 10,001+ on postmark. So maybe the loop should also just break at 10,000.

    Hope that helps. Thanks again for your work!

    opened by silviogutierrez 0
  • Cant attach csv file with UTF-8

    Cant attach csv file with UTF-8

    Hello, I attach csv file with unicode string and send to email with postmark. When I download csv file and open with ms excel the file show wrong string. Not sure what I do wrong ?

            files = []
            csvfile = StringIO()
            writer = csv.writer(csvfile)
            writer.writerow(['some unicode string'])
    
            data = csvfile.getvalue()
            attachment = MIMEBase('text', 'csv')
            attachment.set_payload(data.encode('utf-8'))
            encoders.encode_base64(attachment)
            attachment.add_header('Content-Disposition', 'attachment', filename='readme.csv')
            files.append(attachment)
            
            email = postmark.emails.send_with_template(
                TemplateId=xxx,
                TemplateModel={},
                From='[email protected]',
                To=['[email protected]'],
                Attachments=files
            )
    
    opened by dogrocker 1
Releases(v1.0)
  • v1.0(Jan 15, 2022)

  • v0.18.2(Jun 3, 2021)

    :rocket: Features

    • 288dfe5 Support subject search

    :wrench: Chores and Improvements

    • 92078ef Release 0.18.2

    :package: Other

    • e2c6f1a Fix missing link
    Source code(tar.gz)
    Source code(zip)
  • v0.18.1(May 13, 2021)

  • v0.18.0(May 11, 2021)

    :rocket: Features

    • 33bf3b6 add support for batchWithTemplates

    :wrench: Chores and Improvements

    • a056ae4 Release 0.18.0
    • 1378c30 Update pre-commit hooks

    :package: Other

    • e8dda64 Add a changelog entry
    Source code(tar.gz)
    Source code(zip)
  • v0.17.1(Mar 2, 2021)

    :rocket: Features

    • 37af8e9 root_api_url argument for PostmarkClient

    :wrench: Chores and Improvements

    • f46d0eb Release 0.17.1

    :package: Other

    • a86e138 Fix sphinx warnings
    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Dec 22, 2020)

    :bug: Bug fixes

    • c64348a Make TemplateID not required if TemplateAlias is specified

    :wrench: Chores and Improvements

    • f759727 Release 0.17.0
    • 78fc83c Drop support for Python 3.5

    :package: Other

    • 830462f Merge pull request #191 from Stranger6667/dd/template-alias-fix

    fix: Make TemplateID not required if TemplateAlias is specified

    Source code(tar.gz)
    Source code(zip)
  • v0.16.0(Nov 10, 2020)

    :rocket: Features

    • a96cac8 Implement MessageStream support

    :wrench: Chores and Improvements

    • c42f1e3 Release 0.16.0
    • 814e3c4 Remove obsolete setup.cfg

    :package: Other

    • af4731d Add missing release notes
    • 669189c Add CODE_OF_CONDUCT.md
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Aug 30, 2020)

    :wrench: Chores and Improvements

    • 59871c9 Release 0.15.0
    • a4211f9 Add gitter link
    • edcf364 Add gitter link
    • 5bf9865 Move to src layout
    • d7b92a1 Drop another Python 2 shim
    • 754296a Remove Python 2 shims
    • 3aba8be Apply pylint
    • 5cccb4d Add exception chaining
    • 5c7db7b Apply pre-commit & add GitHub Action job for pre-commit

    :package: Other

    • 9c6e278 Add release job

    • 48080f6 Add GitHub Actions build for Python 3.5-3.9 and PyPy3

    • 415ece4 Drop support for Python 2.7, 3.3, 3.4, PyPy2 and Jython.

    • db20b64 Drop Travis CI

    • 03f4cdf Create FUNDING.yml

    • dd1065f Release 0.14.1

    • 741bbf1 Add missing changelog entry

    • 618d628 Merge remote-tracking branch 'origin/master'

    • 1710940 Code black.

    • b3efc2f At the moment, using the EmailTemplate() doesn't allow Metadata parameters.

    EmailTemplate() now accept Metadata parameters.

    e.g.

    postmark.emails.EmailTemplate(
    	TemplateId=template_id,
    	TemplateAlias=template_alias,
    	From=f"{from_name} {from_}",
    	To=user.email,
    	Headers={"X-Accept-Language": "en-us, en"},
    	TemplateModel=template_model,
    	Metadata=metadata
    )
    
    Source code(tar.gz)
    Source code(zip)
  • v0.14.1(Mar 31, 2020)

  • v0.14.0(Mar 31, 2020)

  • v0.13.1(Mar 31, 2020)

  • 0.13.0(Nov 25, 2018)

    Added

    • Support for Python 3.7. #170
    • Support for Metadata option. #168

    Changed

    • Stream logs to sys.stdout by default. #159

    Removed

    • Support for Python 2.6, 3.2 and 3.3.
    Source code(tar.gz)
    Source code(zip)
  • 0.12.2(Nov 5, 2018)

  • 0.12.1(Nov 5, 2018)

  • 0.12.0(Jun 12, 2018)

    Added

    • Support for TemplateAlias. #150

    Fixed

    • Processing of alternatives together with attachments. #148
    • Processing of message/rfc822 attachments.
    Source code(tar.gz)
    Source code(zip)
  • 0.11.3(Nov 8, 2017)

  • 0.11.2(May 14, 2017)

  • 0.11.1(May 10, 2017)

  • 0.11.0(May 2, 2017)

    • message property for Bounce, Delivery and Open classes to access corresponding OutboundMessage instance. #119
    • An ability to control timeout and retries behaviour. #82
    • Signal for exceptions in Django backend. #126
    • Tornado helper. #85
    Source code(tar.gz)
    Source code(zip)
  • 0.10.1(Apr 3, 2017)

  • 0.10.0(Mar 30, 2017)

    Added

    • Short-circuit send of empty batches in Django backend. #123

    Changed

    • OutboundMessageManager.get_details and InboundMessageManager.get_details were methods were renamed to get. Now they returns OutboundMessage and InboundMessage instances respectively. #125
    • Renamed token kwarg in PostmarkClient to server_token. #130

    Fixed

    • Fix counting of successfully sent messages in Django backend. #122
    • Propagate API exceptions in Django backend. #128
    Source code(tar.gz)
    Source code(zip)
  • 0.9.2(Mar 29, 2017)

  • 0.9.1(Mar 29, 2017)

  • 0.9.0(Mar 28, 2017)

    • Added an ability to load all items without specifying exact count value. #106
    • Added delivery webhook wrapper. #95
    • Added open webhook wrapper. #96
    • Added bounce webhook wrapper. #97
    • Fixed PyPI package display. #116

    Changed

    • postmarker.webhooks.InboundWebhook class was superseded by postmark.messages.inbound.InboundMessage constructor, which works in the same way.
    Source code(tar.gz)
    Source code(zip)
  • 0.8.1(Mar 15, 2017)

  • 0.8.0(Mar 13, 2017)

    • Added an ability to download more than 500 items. #70
    • Added pre_send and post_send Django signals. #83
    • Inbound rules triggers API. #75
    • Changed logs output stream to default sys.stderr. #102
    • Tags triggers API. #74
    Source code(tar.gz)
    Source code(zip)
  • 0.7.2(Mar 11, 2017)

  • 0.7.1(Mar 10, 2017)

  • 0.7.0(Mar 2, 2017)

  • 0.6.2(Jan 3, 2017)

Owner
Dmitry Dygalo
Building a platform for effortless API testing
Dmitry Dygalo
A curated list of awesome Amazon Web Services (AWS) libraries, open source repos, guides, blogs, and other resources.

A curated list of awesome Amazon Web Services (AWS) libraries, open source repos, guides, blogs, and other resources. Featuring the Fiery Meter of AWSome.

Donne Martin 11.1k Jan 04, 2023
Spacecrypto-bot - SpaceCrypto Bot Auto Clicker

SpaceCrypto Auto Clicker Bot Também fiz um para Luna Rush ( https://github.com/w

Walter Discher Cechinel 5 Feb 22, 2022
Bancos de Dados Relacionais (SQL) na AWS com Amazon RDS.

Bancos de Dados Relacionais (SQL) na AWS com Amazon RDS Explorando o Amazon RDS, um serviço de provisionamente e gerenciamento de banco de dados relac

Lucas Magalhães 1 Dec 05, 2021
A simple and easy to use musicbot in python and it uses lavalink.

Lavalink-MusicBot A simple and easy to use musicbot in python and it uses lavalink. ✨ Features plays music in your discord server well thats it i gues

Afnan 1 Nov 29, 2021
A simple Python TDLib wrapper

Telegram Forwarder App Description pywtdlib (Python Wrapper TDLib) is a simple synchronous Python wrapper that makes you easy to create new Python Tel

Álvaro Fernández 2 Jan 04, 2023
A telegram user and chat info extractor with pyrogram python module

Made with Python3 (C) @FayasNoushad Copyright permission under MIT License License - https://github.com/FayasNoushad/Telegram-Info/blob/main/LICENSE

Fayas Noushad 8 Dec 22, 2021
Análise de dados abertos do programa Taxigov.

Análise de dados do Taxigov Este repositório contém os cadernos Jupyter usados no projeto de análise de dados do Taxigov. Conjunto de dados O conjunto

Augusto Herrmann 1 Jan 10, 2022
It's a simple python script to take backup of directories (compressing) then the same to move your mentioned S3 bucket with the help of AWS IAM User.

Directory Backup Moved to S3 (Pyscript) Description Here it's a python script that needs to use this script simply create a directory backup and moved

Yousaf K Hamza 3 Mar 04, 2022
:lock: Python 2.7/3.X client for HashiCorp Vault

hvac HashiCorp Vault API client for Python 3.x Tested against the latest release, HEAD ref, and 3 previous minor versions (counting back from the late

hvac 1k Dec 29, 2022
A script to automatically update bot status at GitHub as well as in Telegram channel.

Support BotStatus ~ A simple & short repository to show your bot's status in your GitHub README.md file as well as in you channel. ⚠️ This repo should

Jainam Oswal 55 Dec 13, 2022
可基于【腾讯云函数】/【GitHub Actions】/【Docker】的每日签到脚本(支持多账号使用)签到列表: |爱奇艺|全民K歌|腾讯视频|有道云笔记|网易云音乐|一加手机社区官方论坛|百度贴吧|Bilibili|V2EX|咔叽网单|什么值得买|AcFun|天翼云盘|WPS|吾爱破解|芒果TV|联通营业厅|Fa米家|小米运动|百度搜索资源平台|每日天气预报|每日一句|哔咔漫画|和彩云|智友邦|微博|CSDN|王者营地|

每日签到集合 基于【腾讯云函数】/【GitHub Actions】/【Docker】的每日签到脚本 支持多账号使用 特别声明: 本仓库发布的脚本及其中涉及的任何解锁和解密分析脚本,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。

87 Nov 12, 2022
:snake: A simple library to fetch data from the iTunes Store API made for Python >= 3.5

itunespy itunespy is a simple library to fetch data from the iTunes Store API made for Python 3.5 and beyond. Important: Since version 1.6 itunespy no

Fran González 56 Dec 22, 2022
Halcyon is a Matrix bot library created with the intention of being easy to install and use. Inspired by discord.py

Halcyon is a Matrix bot library with the goal of being easy to install and use. The library takes inspiration from discord.py and the Slack li

Wes Ring 19 Jan 06, 2023
Python SDK for IEX Cloud

iexfinance Python SDK for IEX Cloud. Architecture mirrors that of the IEX Cloud API (and its documentation). An easy-to-use toolkit to obtain data for

Addison Lynch 640 Jan 07, 2023
Yes, it's true :yellow_heart: This repository has 326 stars.

Yes, it's true! Inspired by a similar repository from @RealPeha, but implemented using a webhook on AWS Lambda and API Gateway, so it's serverless! If

510 Dec 28, 2022
Host your Python Discord Bot 24/7 for free. POC

🐉 Pandore 🐉 The easiest and fastest way to host your Python3 Discord Bot 24/7 for free! 📚 Documentation 📚 If you encounter any problem while using

Billy 73 Jan 02, 2023
The Research PACS on AWS solution facilitates researchers' access medical images stored in the clinical PACS in a secure and seamless manner

Research PACS on AWS Challenge to solve Solution presentation Deploy the solution Further reading Releases License Challenge to solve The rise of new

AWS Samples 23 Sep 09, 2022
Reads and prints information from the website MalAPI.io

MalAPIReader Reads and prints information from the website MalAPI.io optional arguments:

Squiblydoo 16 Nov 10, 2022
Basic Discord python bot

#How to Create a Discord Bot Account In order to work with the Python library and the Discord API, we must first create a Discord Bot account. Here ar

Tustus 1 Oct 13, 2021
Модуль для создания скриптов для ВКонтакте | vk.com API wrapper

vk_api vk_api – Python модуль для создания скриптов для ВКонтакте (vk.com API wrapper) Документация Примеры Чат в Telegram Документация по методам API

Kirill 1.2k Jan 04, 2023