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
This Bot Can Upload Video from Link Of Pdisk to Pdisk using its API. @PredatorHackerzZ

𝐏𝐝𝐢𝐬𝐤 𝐂𝐨𝐧𝐯𝐞𝐫𝐭𝐞𝐫 𝐁𝐨𝐭 Make short link by using 𝐏𝐝𝐢𝐬𝐤 API key Installation 𝐓𝐡𝐞 𝐄𝐚𝐬𝐲 𝐖𝐚𝐲 𝐑𝐞𝐪𝐮𝐢𝐫𝐞𝐝 𝐕𝐚𝐫𝐢𝐚𝐛𝐥𝐞

ρяє∂αтσя 25 Dec 02, 2022
Automatically Message From Discord Account

Discord-AutoMessage A robust and versatile solution for automated social interactions HOW TO INSTALL Open cmd cd into your project directory Run the f

13 Jul 11, 2022
Simplebot-tg - Telegram/DeltaChat Bridge with python

simplebot_tg Telegram/DeltaChat Bridge, is a plugin for https://github.com/simpl

Arián Díaz Cruz 1 Dec 30, 2021
SongBot2.0 With Python

SongBot2.0 Host 👨‍💻 Heroku 🚀 Manditary Vars BOT_TOKEN : Get It from @Botfather Special Feature Downloads Songs fastly and less errors as well as 0

Mr.Tanaji 5 Nov 19, 2021
Make WhatsApp ChatBot and use WhatsApp API to send the WhatsApp messages in python .

Ultramsg.com WhatsApp Bot using WhatsApp API and ultramsg Demo WhatsApp API ChatBot using Ultramsg API with python. Opportunities and tasks: The outpu

Ultramsg 64 Dec 29, 2022
A bot for the [email protected] Discord server.

KittyBot - a sentient Discord bot! Key Notes An open-source, community-powered bot for the [email 

Ollie 11 Dec 06, 2022
A tool for creating credentials for accessing S3 buckets

s3-credentials A tool for creating credentials for accessing S3 buckets For project background, see s3-credentials: a tool for creating credentials fo

Simon Willison 138 Jan 06, 2023
Unencrypted Story View Botter is a helpful tool that allows thousands of people to watch your posts.

Unencrypted Story View Botter is a helpful tool that allows thousands of people to watch your posts.

8 Aug 05, 2022
This is RequestTrackerBot and it used for tracking request made by user in a group

This is a Request Tracker Bot repo, It is for those who upload content like movies, anime, etc. It can be used for tracking request of content that your members asked for.

Abhijeet 27 Dec 29, 2022
My telegram bot to download Instagram Profiles

Instagram Profile Get for Telegram My telegram bot to download Instagram Profiles First you have to get a telegrm bot api key from @BotFather Then you

Ali Yoonesi 2 Sep 22, 2022
This very basic script can be used to automate COVID-19 vaccination slot booking on India's Co-WIN Platform.

COVID-19 Vaccination Slot Booking Script This very basic CLI based script can be used to automate covid vaccination slot booking on Co-WIN Platform. I

605 Dec 14, 2022
PunkScape Discord bot to lookup rarities, create diptychs and more.

PunkScape Discord Bot A Discord bot created for the Discord server of PunkScapes, a banner NFT project. It was intially created to lookup rarities of

Akuti 4 Jun 24, 2022
Calendars for various securities exchanges.

IMPORTANT NOTE This package is currently unmaintained as the sponsor, quantopian, is going through corporate changes. As such there is a fork of this

Quantopian, Inc. 545 Jan 07, 2023
A Telegram Message Manager Bot by @AbirHasan2005

Messages-Manager-Bot A Telegram Message Manager Bot by @AbirHasan2005. This Bot can delete specific type of messages from Group. I specially use for @

Abir Hasan 32 Nov 12, 2022
Shellkg-py - A temporary Repository to rewrite of shellpkg in python

Shellkg-py - A temporary Repository to rewrite of shellpkg in python

2 Jan 26, 2022
Fully undetected auto skillcheck hack for dead by daylight that works decently well

Auto-skillcheck was made by Love ❌ code ✅ ❔ ・How to use Start off by installing python ofc Open cmd in the same directory and type pip install -r requ

Rdimo 10 Aug 13, 2022
Amazon AWS Web Tool (view only)

Amazon AWS Web Tool (AAWT) discontinued Features Cloudfront (simple) EC2 (With Charts and Prices) EC2 Reserved EBS ELB (With Charts) Obs:. only classi

Carlos Augusto Malucelli 9 Nov 07, 2022
This is a okay that is okay that means none is okay

Owner: Masterolic 🇮🇳 CatUB A Powerful, Smart And Simple Userbot In Telethon. Credits This is A Remix Bot Of Many UserBot. DARKCOBRA FridayUserBot Ja

Masterolic 1 Nov 28, 2021
Revolt account generator. Bypassing Hcaptcha using AI solver.

RevoltGenerator Revolt account generator. Bypassing Hcaptcha using AI solver. Config settings in config.json then put your usernames / proxies. If you

&! Ѵιchy.#0110 27 Nov 01, 2022
Start multiple bots using one script. VK RAID BOTNET

MultiRaidBotnet Start multiple bots using one script. VK RAID BOTNET Русский launcher.py - главный скрипт, запускающий весь ботнет config.py - в нём х

2 Jul 22, 2022