Mailjet API implementation in Python

Overview
READ THIS FIRST!!
This repository isn't compatible with the current Mailjet API (v3) and, as a consequence, is considered deprecated and won't undergo further development. As such, this repository isn't under active maintenance.

Introduction

Mailjet is a real-time Cloud Emailing platform and this is a python library to access the Mailjet Web API.

Installation

  • Clone this repository:

git clone https://github.com/WoLpH/mailjet

  • cd into the cloned directory and execute:

python setup.py install.

The settings can be configured from a Django settings file through MAILJET_API_KEY and MAILJET_SECRET_KEY, or through environment variables with the same name.

i.e.

export MAILJET_API_KEY='YOUR_API_KEY'
export MAILJET_SECRET_KEY='YOUR_SECRET_KEY'

Alternatively, you can just pass the API key and Secret key as parameters when initializing the mailjet API as follows:

import mailjet

mailjet_api = mailjet.Api(api_key='YOUR_API_KEY', secret_key='YOUR_SECRET_KEY')

Usage

  • To get your account and profile information:
import mailjet

mailjet_api = mailjet.Api(api_key='YOUR_API_KEY', secret_key='YOUR_SECRET_KEY')
account_info = mailjet_api.user.infos()

acount_info would now be assigned the following python dict:

{
    'status': 'OK',
    'infos': {
        'username': '[email protected]',
        'firstname': 'firstname',
        'locale': 'en_US',
        'lastname': 'lastname',
        'company_name': 'company_name',
        'contact_phone': None,
    }
}
  • Create a new list of contacts, following on from the previous example:
contact_list = mailjet_api.lists.create(
    label='test',
    name='testlist',  # Only alphanumeric characters are allowed!
    method='POST'
)

contact_list will now contain a dictionary with the status and list id as below:

{
    'status': 'OK',
    'contact_id': 000000000
}
  • You can now add contacts to your list using the contact_id:
mailjet_api.lists.addcontact(
    contact='[email protected]',
    id=contact_list['list_id'],
    method='POST'
)

FAQ

How do I give reserved python keywords as parameters?

Methods such as creating a campaign require you to use reserved python keywords, such as from - hence, in order to overcome this, do the following:

params = dict()
params['method'] ='POST'
params['subject'] = 'My first campaign'
params['list_id'] = contact_list['list_id']
params['lang'] = 'en'
params['from'] = '[email protected]'
params['from_name'] = 'Your name'
params['footer'] = 'default'
campaign = mailjet_api.message.createcampaign(**params)

How do I debug errors?

The errors produced by the mailjet library (or actually, produced by the urllib2 library) are still normal http responses. So if you wish to read the actual response, do something like this:

try:
    contact_list = mailjet_api.lists.create(
        label='test',
        name='Test list',  # Incorrect because of the space in the name
        method='POST'
    )
except Exception, e:
    print 'Mailjet response: %r, %r' % (e, e.read())
Comments
  • Improvements to get people started more easily

    Improvements to get people started more easily

    Hello,

    I attended AngelHack London 2013 a few weeks ago and when trying to use the Mailjet python library it was apparent that the documentation/examples were not very clear and in some places wrong, so I have made a few improvements to enable people to get up and running with Mailjet's python library in no time.

    I hope this helps!

    opened by AnSavvides 4
  • Inconsistency in list_id type

    Inconsistency in list_id type

    list_id is returned as an int in api.lists.create()

       ipdb> n
       > env/src/mailjet/mailjet/contrib/django_mailjet/forms.py(67)list_create()
            66         l = self.api.lists.create(label=self.list_label, name=self.list_name,
       ---> 67                 method='POST')
            68  
       
       ipdb> 
       > env/src/mailjet/mailjet/contrib/django_mailjet/forms.py(69)list_create()
            67                 method='POST')
            68  
       ---> 69         return l['list_id']
       
       ipdb> print l
       {u'status': u'OK', u'list_id': 398253}
    

    But as a unicode string in api.lists.all():

       ---> 34         for l in self.api.lists.all()['lists']:
             35             if l['id'] == list_id:
    
        ipdb> print l
        {u'name': u'foo', u'spam': u'0', u'created_at': u'1378992123', u'bounce': u'0', u'label': u'bar', u'click': u'0', u'last_activity': None, u'handled': u'1', u'subscribers': u'0', u'unsub': u'0', u'open': u'0', u'id': u'398253', u'sent': u'0', u'blocked': u'0'}
    

    And of course, this results in odd results:

    ipdb> print l['id'] == list_id
    False
    ipdb> print list_id
    398246
    ipdb> print l['id']
    398246
    

    I know it's probably a bug from mailjet.com API, but maybe we could fix this inside the python mailjet package or maybe you could recommend a best practice (convert all to string ?)

    Thanks

    opened by jpic 3
  • Fix for passing tuple to as Api argument value

    Fix for passing tuple to as Api argument value

    Workarround to pass tuple as argument in the form that mailjet api understand : Ex food=('chocolate', 'cookie') is now transform in request to food[0]=chocolate&food[1]=cookie

    opened by brvier 2
  • Add basic subscription functionality

    Add basic subscription functionality

    Maybe it would be cool if django-mailjet had:

    • settings: MAILJET_LIST_NAME, MAILJET_LIST_LABEL
    • forms.SubscriptionForm with API calls, using the above settings,
    • urls: mailjet_subscription (using FormView with SubscriptionForm) and mailjet_subscription_success (using a TemplateView)
    • mailjet/templates/mailjet/{subscription_form.html,subscription_success.html}

    I have implemented exactly that on my own (in a project app) and it is generic - as a matter of fact it's a good example of django's great support for pluggables. Of course, it would not be any use for projects handling several lists, but it would be completely optional and could be cool to have in most case and used as a start.

    What's your opinion ?

    Is it worth making a pull request ?

    Also, it looks like django-mailjet evolved in a non-django-specific library, so maybe this could go in mailjet.contrib.django to avoid polluting the package root namespace ?

    Or should this be released in a completely separate app ?

    opened by jpic 2
  • Can't create list, 400 BadRequest

    Can't create list, 400 BadRequest

    After following the documentation, I made it to this point:

    contact_list = mailjet_api.lists.create(
        label='test',
        name='Test list',
        method='POST'
    )
    

    But instead of:

    {
        'status': 'OK',
        'contact_id': 000000000
    }
    

    This is what it looks like:

    In [1]: import mailjet
    
    In [2]: mailjet_api = mailjet.Api()
    
    In [3]: account_info = mailjet_api.user.infos()
    
    In [4]: account_info
    Out[4]: 
    {u'infos': {u'address_city': u'Paris',
      u'address_country': u'FR',
      u'address_postal_code': u'75999',
      u'address_street': u'7 rue oeuoeuaoeu',
      u'company_name': u'',
      u'contact_phone': u'0123456789',
      u'currency': u'EUR',
      u'email': u'[email protected]',
      u'firstname': u'James',
      u'lastname': u'Pic',
      u'locale': u'en_EU',
      u'timezone': u'Europe/Paris',
      u'tracking_clicks': u'1',
      u'tracking_openers': u'1',
      u'username': u'[email protected]'},
     u'status': u'OK'}
    
    In [5]: contact_list = mailjet_api.lists.create(
        label='test5',
        name='Test list 5',
        method='POST'
    )
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2013-09-10 17:22:15.227605) while time zone support is active.
      RuntimeWarning)
    
    ---------------------------------------------------------------------------
    HTTPError                                 Traceback (most recent call last)
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
          2     label='test5',
          3     name='Test list 5',
    ----> 4     method='POST'
          5 )
    
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/mailjet/api.py in __call__(self, **kwargs)
         40             self.function,
         41             options=options,
    ---> 42             postdata=postdata,
         43         )
         44         return json.load(response)
    
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/mailjet/connection.pyc in open(self, method, function, options, postdata)
         48 
         49         opener = self.get_opener(url)
    ---> 50         return opener.open(url, poststring, self.timeout)
         51 
         52     @classmethod
    
    /usr/lib/python2.7/urllib2.pyc in open(self, fullurl, data, timeout)
        408         for processor in self.process_response.get(protocol, []):
        409             meth = getattr(processor, meth_name)
    --> 410             response = meth(req, response)
        411 
        412         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_response(self, request, response)
        521         if not (200 <= code < 300):
        522             response = self.parent.error(
    --> 523                 'http', request, response, code, msg, hdrs)
        524 
        525         return response
    
    /usr/lib/python2.7/urllib2.pyc in error(self, proto, *args)
        440             http_err = 0
        441         args = (dict, proto, meth_name) + args
    --> 442         result = self._call_chain(*args)
        443         if result:
        444             return result
    
    /usr/lib/python2.7/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        380             func = getattr(handler, meth_name)
        381 
    --> 382             result = func(*args)
        383             if result is not None:
        384                 return result
    
    /usr/lib/python2.7/urllib2.pyc in http_error_401(self, req, fp, code, msg, headers)
        895         url = req.get_full_url()
        896         response = self.http_error_auth_reqed('www-authenticate',
    --> 897                                               url, req, headers)
        898         self.reset_retry_count()
        899         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_error_auth_reqed(self, authreq, host, req, headers)
        870                                   UserWarning, 2)
        871                 if scheme.lower() == 'basic':
    --> 872                     response = self.retry_http_basic_auth(host, req, realm)
        873                     if response and response.code != 401:
        874                         self.retried = 0
    
    /usr/lib/python2.7/urllib2.pyc in retry_http_basic_auth(self, host, req, realm)
        883                 return None
        884             req.add_unredirected_header(self.auth_header, auth)
    --> 885             return self.parent.open(req, timeout=req.timeout)
        886         else:
        887             return None
    
    /usr/lib/python2.7/urllib2.pyc in open(self, fullurl, data, timeout)
        408         for processor in self.process_response.get(protocol, []):
        409             meth = getattr(processor, meth_name)
    --> 410             response = meth(req, response)
        411 
        412         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_response(self, request, response)
        521         if not (200 <= code < 300):
        522             response = self.parent.error(
    --> 523                 'http', request, response, code, msg, hdrs)
        524 
        525         return response
    
    /usr/lib/python2.7/urllib2.pyc in error(self, proto, *args)
        446         if http_err:
        447             args = (dict, 'default', 'http_error_default') + orig_args
    --> 448             return self._call_chain(*args)
        449 
        450 # XXX probably also want an abstract factory that knows when it makes
    
    /usr/lib/python2.7/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        380             func = getattr(handler, meth_name)
        381 
    --> 382             result = func(*args)
        383             if result is not None:
        384                 return result
    
    /usr/lib/python2.7/urllib2.pyc in http_error_default(self, req, fp, code, msg, hdrs)
        529 class HTTPDefaultErrorHandler(BaseHandler):
        530     def http_error_default(self, req, fp, code, msg, hdrs):
    --> 531         raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
        532 
        533 class HTTPRedirectHandler(BaseHandler):
    
    HTTPError: HTTP Error 400: Bad Request
    

    At first I thought it was a problem with capitalisation, but I tried with Create and it doesn't work either (note: I added some print statements to make it easier to debug):

    In [8]: contact_list = mailjet_api.lists.Create(
        label='test5',
        name='Test list 5',
        method='POST'
    )
    <mailjet.api.ApiMethod object at 0x9bb466c> Create None {'name': 'Test list 5', 'label': 'test5'}
    <urllib2.OpenerDirector instance at 0x9ba9c6c> https://api.mailjet.com/0.1/listsCreate?output=json name=Test+list+5&label=test5
    ---------------------------------------------------------------------------
    HTTPError                                 Traceback (most recent call last)
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/django/core/management/commands/shell.pyc in <module>()
          2     label='test5',
          3     name='Test list 5',
    ----> 4     method='POST'
          5 )
    
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/mailjet/api.pyc in __call__(self, **kwargs)
         41             self.function,
         42             options=options,
    ---> 43             postdata=postdata,
         44         )
         45         return json.load(response)
    
    /home/jpic/jousse/jousse_env/local/lib/python2.7/site-packages/mailjet/connection.py in open(self, method, function, options, postdata)
         49         opener = self.get_opener(url)
         50         print opener, url, poststring
    ---> 51         return opener.open(url, poststring, self.timeout)
         52 
         53     @classmethod
    
    /usr/lib/python2.7/urllib2.pyc in open(self, fullurl, data, timeout)
        408         for processor in self.process_response.get(protocol, []):
        409             meth = getattr(processor, meth_name)
    --> 410             response = meth(req, response)
        411 
        412         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_response(self, request, response)
        521         if not (200 <= code < 300):
        522             response = self.parent.error(
    --> 523                 'http', request, response, code, msg, hdrs)
        524 
        525         return response
    
    /usr/lib/python2.7/urllib2.pyc in error(self, proto, *args)
        440             http_err = 0
        441         args = (dict, proto, meth_name) + args
    --> 442         result = self._call_chain(*args)
        443         if result:
        444             return result
    
    /usr/lib/python2.7/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        380             func = getattr(handler, meth_name)
        381 
    --> 382             result = func(*args)
        383             if result is not None:
        384                 return result
    
    /usr/lib/python2.7/urllib2.pyc in http_error_401(self, req, fp, code, msg, headers)
        895         url = req.get_full_url()
        896         response = self.http_error_auth_reqed('www-authenticate',
    --> 897                                               url, req, headers)
        898         self.reset_retry_count()
        899         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_error_auth_reqed(self, authreq, host, req, headers)
        870                                   UserWarning, 2)
        871                 if scheme.lower() == 'basic':
    --> 872                     response = self.retry_http_basic_auth(host, req, realm)
        873                     if response and response.code != 401:
        874                         self.retried = 0
    
    /usr/lib/python2.7/urllib2.pyc in retry_http_basic_auth(self, host, req, realm)
        883                 return None
        884             req.add_unredirected_header(self.auth_header, auth)
    --> 885             return self.parent.open(req, timeout=req.timeout)
        886         else:
        887             return None
    
    /usr/lib/python2.7/urllib2.pyc in open(self, fullurl, data, timeout)
        408         for processor in self.process_response.get(protocol, []):
        409             meth = getattr(processor, meth_name)
    --> 410             response = meth(req, response)
        411 
        412         return response
    
    /usr/lib/python2.7/urllib2.pyc in http_response(self, request, response)
        521         if not (200 <= code < 300):
        522             response = self.parent.error(
    --> 523                 'http', request, response, code, msg, hdrs)
        524 
        525         return response
    
    /usr/lib/python2.7/urllib2.pyc in error(self, proto, *args)
        446         if http_err:
        447             args = (dict, 'default', 'http_error_default') + orig_args
    --> 448             return self._call_chain(*args)
        449 
        450 # XXX probably also want an abstract factory that knows when it makes
    
    /usr/lib/python2.7/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        380             func = getattr(handler, meth_name)
        381 
    --> 382             result = func(*args)
        383             if result is not None:
        384                 return result
    
    /usr/lib/python2.7/urllib2.pyc in http_error_default(self, req, fp, code, msg, hdrs)
        529 class HTTPDefaultErrorHandler(BaseHandler):
        530     def http_error_default(self, req, fp, code, msg, hdrs):
    --> 531         raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
        532 
        533 class HTTPRedirectHandler(BaseHandler):
    
    HTTPError: HTTP Error 400: Bad Request
    
    opened by jpic 2
  • Sethtmlcampaign issue

    Sethtmlcampaign issue

    When i use the function : api.message.sethtmlcampaign(method='POST', id=campaign_['campaign']['id'], html='test', text='hello world')

    That respond to me : HTTPError: HTTP Error 400: Bad Request

    Then i cant put html on my mails ! Any idea?

    opened by nini29 2
  • docs: Fix a few typos

    docs: Fix a few typos

    There are small typos in:

    • README.rst
    • docs/conf.py
    • mailjet/settings.py

    Fixes:

    • Should read that rather than shat.
    • Should read supported rather than suported.
    • Should read account rather than acount.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 1
  • Bump django from 1.9.8 to 1.11.29

    Bump django from 1.9.8 to 1.11.29

    Bumps django from 1.9.8 to 1.11.29.

    Commits
    • f1e3017 [1.11.x] Bumped version for 1.11.29 release.
    • 02d97f3 [1.11.x] Fixed CVE-2020-9402 -- Properly escaped tolerance parameter in GIS f...
    • e643833 [1.11.x] Pinned PyYAML < 5.3 in test requirements.
    • d0e3eb8 [1.11.x] Added CVE-2020-7471 to security archive.
    • 9a62ed5 [1.11.x] Post-release version bump.
    • e09f09b [1.11.x] Bumped version for 1.11.28 release.
    • 001b063 [1.11.x] Fixed CVE-2020-7471 -- Properly escaped StringAgg(delimiter) parameter.
    • 7fd1ca3 [1.11.x] Fixed timezones tests for PyYAML 5.3+.
    • 121115d [1.11.x] Added CVE-2019-19844 to the security archive.
    • 2c4fb9a [1.11.x] Post-release version bump.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump django from 1.9.8 to 1.11.28

    Bump django from 1.9.8 to 1.11.28

    Bumps django from 1.9.8 to 1.11.28.

    Commits
    • e09f09b [1.11.x] Bumped version for 1.11.28 release.
    • 001b063 [1.11.x] Fixed CVE-2020-7471 -- Properly escaped StringAgg(delimiter) parameter.
    • 7fd1ca3 [1.11.x] Fixed timezones tests for PyYAML 5.3+.
    • 121115d [1.11.x] Added CVE-2019-19844 to the security archive.
    • 2c4fb9a [1.11.x] Post-release version bump.
    • 358973a [1.11.x] Bumped version for 1.11.27 release.
    • f4cff43 [1.11.x] Fixed CVE-2019-19844 -- Used verified user email for password reset ...
    • a235574 [1.11.x] Refs #31073 -- Added release notes for 02eff7ef60466da108b1a33f1e4dc...
    • e8fdf00 [1.11.x] Fixed #31073 -- Prevented CheckboxInput.get_context() from mutating ...
    • 4f15016 [1.11.x] Post-release version bump.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • ValueError: No JSON object could be decoded

    ValueError: No JSON object could be decoded

    An exception is raised when mailjet API returns nothing (ie. empty string).

    For example, calling api.lists.all() when there is no list causes mailjet to return with nothing instead of an empty list. Thus, json.load() crashes:

    Traceback (most recent call last):
      File "env/src/mailjet/mailjet/contrib/django_mailjet/tests.py", line 12, in setUpClass
        lists = mailjet.Api().lists.all()
      File "env/src/mailjet/mailjet/api.py", line 45, in __call__
        return json.load(response)
      File "/usr/lib/python2.7/json/__init__.py", line 290, in load
        **kw)
      File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
        return _default_decoder.decode(s)
      File "/usr/lib/python2.7/json/decoder.py", line 365, in decode
        obj, end = self.raw_decode(s, idx=_w(s, 0).end())
      File "/usr/lib/python2.7/json/decoder.py", line 383, in raw_decode
        raise ValueError("No JSON object could be decoded")
    ValueError: No JSON object could be decoded
    

    Shouldn't the Api return None if mailjet responds with nothing '' ?

    opened by jpic 1
  • Not able to create a simple list

    Not able to create a simple list

    Folks, the documentation seems to be incorrect. Not able to create a simple list via the following:

    import mailjet
    mailjet_api = mailjet.Api(api_key='x', secret_key='y')
    contact_list = mailjet_api.lists.create(label='test',name='Test list',method='POST')
    

    Receive:

    HTTPError                                 Traceback (most recent call last)
    <ipython-input-6-9260c9fd8821> in <module>()
    ----> 1 contact_list = mailjet_api.lists.create(label='test',name='Test list',method='POST')
    
    /usr/lib/python2.6/site-packages/mailjet-1.3.1-py2.6.egg/mailjet/api.pyc in __call__(self, **kwargs)
         40             self.function,
         41             options=options,
    ---> 42             postdata=postdata,
         43         )
         44         return json.load(response)
    
    /usr/lib/python2.6/site-packages/mailjet-1.3.1-py2.6.egg/mailjet/connection.pyc in open(self, method, function, options, postdata)
         48
         49         opener = self.get_opener(url)
    ---> 50         return opener.open(url, poststring, self.timeout)
         51
         52     @classmethod
    
    /usr/lib64/python2.6/urllib2.pyc in open(self, fullurl, data, timeout)
        395         for processor in self.process_response.get(protocol, []):
        396             meth = getattr(processor, meth_name)
    --> 397             response = meth(req, response)
        398
        399         return response
    
    /usr/lib64/python2.6/urllib2.pyc in http_response(self, request, response)
        508         if not (200 <= code < 300):
        509             response = self.parent.error(
    --> 510                 'http', request, response, code, msg, hdrs)
        511
        512         return response
    
    /usr/lib64/python2.6/urllib2.pyc in error(self, proto, *args)
        427             http_err = 0
        428         args = (dict, proto, meth_name) + args
    --> 429         result = self._call_chain(*args)
        430         if result:
        431             return result
    
    /usr/lib64/python2.6/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        367             func = getattr(handler, meth_name)
        368
    --> 369             result = func(*args)
        370             if result is not None:
        371                 return result
    
    /usr/lib64/python2.6/urllib2.pyc in http_error_401(self, req, fp, code, msg, headers)
        878         url = req.get_full_url()
        879         response = self.http_error_auth_reqed('www-authenticate',
    --> 880                                               url, req, headers)
        881         self.reset_retry_count()
        882         return response
    
    /usr/lib64/python2.6/urllib2.pyc in http_error_auth_reqed(self, authreq, host, req, headers)
        856                 scheme, quote, realm = mo.groups()
        857                 if scheme.lower() == 'basic':
    --> 858                     return self.retry_http_basic_auth(host, req, realm)
        859
        860     def retry_http_basic_auth(self, host, req, realm):
    
    /usr/lib64/python2.6/urllib2.pyc in retry_http_basic_auth(self, host, req, realm)
        866                 return None
        867             req.add_unredirected_header(self.auth_header, auth)
    --> 868             return self.parent.open(req, timeout=req.timeout)
        869         else:
        870             return None
    
    /usr/lib64/python2.6/urllib2.pyc in open(self, fullurl, data, timeout)
        395         for processor in self.process_response.get(protocol, []):
        396             meth = getattr(processor, meth_name)
    --> 397             response = meth(req, response)
        398
        399         return response
    
    /usr/lib64/python2.6/urllib2.pyc in http_response(self, request, response)
        508         if not (200 <= code < 300):
        509             response = self.parent.error(
    --> 510                 'http', request, response, code, msg, hdrs)
        511
        512         return response
    
    /usr/lib64/python2.6/urllib2.pyc in error(self, proto, *args)
        433         if http_err:
        434             args = (dict, 'default', 'http_error_default') + orig_args
    --> 435             return self._call_chain(*args)
        436
        437 # XXX probably also want an abstract factory that knows when it makes
    
    /usr/lib64/python2.6/urllib2.pyc in _call_chain(self, chain, kind, meth_name, *args)
        367             func = getattr(handler, meth_name)
        368
    --> 369             result = func(*args)
        370             if result is not None:
        371                 return result
    
    /usr/lib64/python2.6/urllib2.pyc in http_error_default(self, req, fp, code, msg, hdrs)
        516 class HTTPDefaultErrorHandler(BaseHandler):
        517     def http_error_default(self, req, fp, code, msg, hdrs):
    --> 518         raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
        519
        520 class HTTPRedirectHandler(BaseHandler):
    
    HTTPError: HTTP Error 400: Bad Request
    
    opened by vasiliyb 1
  • Bump django from 1.9.8 to 2.2.24

    Bump django from 1.9.8 to 2.2.24

    Bumps django from 1.9.8 to 2.2.24.

    Commits
    • 2da029d [2.2.x] Bumped version for 2.2.24 release.
    • f27c38a [2.2.x] Fixed CVE-2021-33571 -- Prevented leading zeros in IPv4 addresses.
    • 053cc95 [2.2.x] Fixed CVE-2021-33203 -- Fixed potential path-traversal via admindocs'...
    • 6229d87 [2.2.x] Confirmed release date for Django 2.2.24.
    • f163ad5 [2.2.x] Added stub release notes and date for Django 2.2.24.
    • bed1755 [2.2.x] Changed IRC references to Libera.Chat.
    • 63f0d7a [2.2.x] Refs #32718 -- Fixed file_storage.test_generate_filename and model_fi...
    • 5fe4970 [2.2.x] Post-release version bump.
    • 61f814f [2.2.x] Bumped version for 2.2.23 release.
    • b8ecb06 [2.2.x] Fixed #32718 -- Relaxed file name validation in FileField.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump py from 1.4.31 to 1.10.0

    Bump py from 1.4.31 to 1.10.0

    Bumps py from 1.4.31 to 1.10.0.

    Changelog

    Sourced from py's changelog.

    1.10.0 (2020-12-12)

    • Fix a regular expression DoS vulnerability in the py.path.svnwc SVN blame functionality (CVE-2020-29651)
    • Update vendored apipkg: 1.4 => 1.5
    • Update vendored iniconfig: 1.0.0 => 1.1.1

    1.9.0 (2020-06-24)

    • Add type annotation stubs for the following modules:

      • py.error
      • py.iniconfig
      • py.path (not including SVN paths)
      • py.io
      • py.xml

      There are no plans to type other modules at this time.

      The type annotations are provided in external .pyi files, not inline in the code, and may therefore contain small errors or omissions. If you use py in conjunction with a type checker, and encounter any type errors you believe should be accepted, please report it in an issue.

    1.8.2 (2020-06-15)

    • On Windows, py.path.locals which differ only in case now have the same Python hash value. Previously, such paths were considered equal but had different hashes, which is not allowed and breaks the assumptions made by dicts, sets and other users of hashes.

    1.8.1 (2019-12-27)

    • Handle FileNotFoundError when trying to import pathlib in path.common on Python 3.4 (#207).

    • py.path.local.samefile now works correctly in Python 3 on Windows when dealing with symlinks.

    1.8.0 (2019-02-21)

    • add "importlib" pyimport mode for python3.5+, allowing unimportable test suites to contain identically named modules.

    • fix LocalPath.as_cwd() not calling os.chdir() with None, when being invoked from a non-existing directory.

    ... (truncated)

    Commits
    • e5ff378 Update CHANGELOG for 1.10.0
    • 94cf44f Update vendored libs
    • 5e8ded5 testing: comment out an assert which fails on Python 3.9 for now
    • afdffcc Rename HOWTORELEASE.rst to RELEASING.rst
    • 2de53a6 Merge pull request #266 from nicoddemus/gh-actions
    • fa1b32e Merge pull request #264 from hugovk/patch-2
    • 887d6b8 Skip test_samefile_symlink on pypy3 on Windows
    • e94e670 Fix test_comments() in test_source
    • fef9a32 Adapt test
    • 4a694b0 Add GitHub Actions badge to README
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump pygments from 2.1.3 to 2.7.4

    Bump pygments from 2.1.3 to 2.7.4

    Bumps pygments from 2.1.3 to 2.7.4.

    Release notes

    Sourced from pygments's releases.

    2.7.4

    • Updated lexers:

      • Apache configurations: Improve handling of malformed tags (#1656)

      • CSS: Add support for variables (#1633, #1666)

      • Crystal (#1650, #1670)

      • Coq (#1648)

      • Fortran: Add missing keywords (#1635, #1665)

      • Ini (#1624)

      • JavaScript and variants (#1647 -- missing regex flags, #1651)

      • Markdown (#1623, #1617)

      • Shell

        • Lex trailing whitespace as part of the prompt (#1645)
        • Add missing in keyword (#1652)
      • SQL - Fix keywords (#1668)

      • Typescript: Fix incorrect punctuation handling (#1510, #1511)

    • Fix infinite loop in SML lexer (#1625)

    • Fix backtracking string regexes in JavaScript/TypeScript, Modula2 and many other lexers (#1637)

    • Limit recursion with nesting Ruby heredocs (#1638)

    • Fix a few inefficient regexes for guessing lexers

    • Fix the raw token lexer handling of Unicode (#1616)

    • Revert a private API change in the HTML formatter (#1655) -- please note that private APIs remain subject to change!

    • Fix several exponential/cubic-complexity regexes found by Ben Caller/Doyensec (#1675)

    • Fix incorrect MATLAB example (#1582)

    Thanks to Google's OSS-Fuzz project for finding many of these bugs.

    2.7.3

    ... (truncated)

    Changelog

    Sourced from pygments's changelog.

    Version 2.7.4

    (released January 12, 2021)

    • Updated lexers:

      • Apache configurations: Improve handling of malformed tags (#1656)

      • CSS: Add support for variables (#1633, #1666)

      • Crystal (#1650, #1670)

      • Coq (#1648)

      • Fortran: Add missing keywords (#1635, #1665)

      • Ini (#1624)

      • JavaScript and variants (#1647 -- missing regex flags, #1651)

      • Markdown (#1623, #1617)

      • Shell

        • Lex trailing whitespace as part of the prompt (#1645)
        • Add missing in keyword (#1652)
      • SQL - Fix keywords (#1668)

      • Typescript: Fix incorrect punctuation handling (#1510, #1511)

    • Fix infinite loop in SML lexer (#1625)

    • Fix backtracking string regexes in JavaScript/TypeScript, Modula2 and many other lexers (#1637)

    • Limit recursion with nesting Ruby heredocs (#1638)

    • Fix a few inefficient regexes for guessing lexers

    • Fix the raw token lexer handling of Unicode (#1616)

    • Revert a private API change in the HTML formatter (#1655) -- please note that private APIs remain subject to change!

    • Fix several exponential/cubic-complexity regexes found by Ben Caller/Doyensec (#1675)

    • Fix incorrect MATLAB example (#1582)

    Thanks to Google's OSS-Fuzz project for finding many of these bugs.

    Version 2.7.3

    (released December 6, 2020)

    ... (truncated)

    Commits
    • 4d555d0 Bump version to 2.7.4.
    • fc3b05d Update CHANGES.
    • ad21935 Revert "Added dracula theme style (#1636)"
    • e411506 Prepare for 2.7.4 release.
    • 275e34d doc: remove Perl 6 ref
    • 2e7e8c4 Fix several exponential/cubic complexity regexes found by Ben Caller/Doyensec
    • eb39c43 xquery: fix pop from empty stack
    • 2738778 fix coding style in test_analyzer_lexer
    • 02e0f09 Added 'ERROR STOP' to fortran.py keywords. (#1665)
    • c83fe48 support added for css variables (#1633)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump jinja2 from 2.8 to 2.11.3

    Bump jinja2 from 2.8 to 2.11.3

    Bumps jinja2 from 2.8 to 2.11.3.

    Release notes

    Sourced from jinja2's releases.

    2.11.3

    This contains a fix for a speed issue with the urlize filter. urlize is likely to be called on untrusted user input. For certain inputs some of the regular expressions used to parse the text could take a very long time due to backtracking. As part of the fix, the email matching became slightly stricter. The various speedups apply to urlize in general, not just the specific input cases.

    2.11.2

    2.11.1

    This fixes an issue in async environment when indexing the result of an attribute lookup, like {{ data.items[1:] }}.

    2.11.0

    This is the last version to support Python 2.7 and 3.5. The next version will be Jinja 3.0 and will support Python 3.6 and newer.

    2.10.3

    2.10.2

    2.10.1

    2.10

    Primary changes

    Install or upgrade

    Install from PyPI with pip:

    ... (truncated)

    Changelog

    Sourced from jinja2's changelog.

    Version 2.11.3

    Released 2021-01-31

    • Improve the speed of the urlize filter by reducing regex backtracking. Email matching requires a word character at the start of the domain part, and only word characters in the TLD. :pr:1343

    Version 2.11.2

    Released 2020-04-13

    • Fix a bug that caused callable objects with __getattr__, like :class:~unittest.mock.Mock to be treated as a :func:contextfunction. :issue:1145
    • Update wordcount filter to trigger :class:Undefined methods by wrapping the input in :func:soft_str. :pr:1160
    • Fix a hang when displaying tracebacks on Python 32-bit. :issue:1162
    • Showing an undefined error for an object that raises AttributeError on access doesn't cause a recursion error. :issue:1177
    • Revert changes to :class:~loaders.PackageLoader from 2.10 which removed the dependency on setuptools and pkg_resources, and added limited support for namespace packages. The changes caused issues when using Pytest. Due to the difficulty in supporting Python 2 and :pep:451 simultaneously, the changes are reverted until 3.0. :pr:1182
    • Fix line numbers in error messages when newlines are stripped. :pr:1178
    • The special namespace() assignment object in templates works in async environments. :issue:1180
    • Fix whitespace being removed before tags in the middle of lines when lstrip_blocks is enabled. :issue:1138
    • :class:~nativetypes.NativeEnvironment doesn't evaluate intermediate strings during rendering. This prevents early evaluation which could change the value of an expression. :issue:1186

    Version 2.11.1

    Released 2020-01-30

    • Fix a bug that prevented looking up a key after an attribute ({{ data.items[1:] }}) in an async template. :issue:1141

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Owner
Rick van Hattem
Author of @mastering-python and entrepreneur interested in scaling large and complicated systems.
Rick van Hattem
alpaca-trade-api-python is a python library for the Alpaca Commission Free Trading API.

alpaca-trade-api-python is a python library for the Alpaca Commission Free Trading API. It allows rapid trading algo development easily, with support for both REST and streaming data interfaces

Alpaca 1.5k Jan 9, 2023
WhatsApp Api Python - This documentation aims to exemplify the use of Moorse Whatsapp API in Python

WhatsApp API Python ChatBot Este repositório contém uma aplicação que se utiliza

Moorse.io 3 Jan 8, 2022
Official python API for Phish.AI public and private API to detect zero-day phishing websites

phish-ai-api Summary Official python API for Phish.AI public and private API to detect zero-day phishing websites How it Works (TLDR) Essentially we h

Phish.AI 168 May 17, 2022
Python API wrapper around Trello's API

A wrapper around the Trello API written in Python. Each Trello object is represented by a corresponding Python object. The attributes of these objects

Richard Kolkovich 904 Jan 2, 2023
A python to scratch API connector. Can fetch data from the API and send it back in cloud variables.

Scratch2py Scratch2py or S2py is a easy to use, versatile tool to communicate with the Scratch API Based of scratchclient by Raihan142857 Installation

null 20 Jun 18, 2022
Async ready API wrapper for Revolt API written in Python.

Mutiny Async ready API wrapper for Revolt API written in Python. Installation Python 3.9 or higher is required To install the library, you can just ru

null 16 Mar 29, 2022
🚀 An asynchronous python API wrapper meant to replace discord.py - Snappy discord api wrapper written with aiohttp & websockets

Pincer An asynchronous python API wrapper meant to replace discord.py ❗ The package is currently within the planning phase ?? Links |Join the discord

Pincer 125 Dec 26, 2022
wyscoutapi is an extremely basic API client for the Wyscout API (v2 & v3) for Python

wyscoutapi wyscoutapi is an extremely basic API client for the Wyscout API (v2 & v3). Usage Install with pip install wyscoutapi. To connect to the Wys

Ben Torvaney 11 Nov 22, 2022
Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Harun Mbaabu Mwenda 46 Sep 1, 2022
A Python API wrapper for the Twitter API!

PyTweet PyTweet is an api wrapper made for twitter using twitter's api version 2! Installation Windows py3 -m pip install PyTweet Linux python -m pip

TheFarGG 1 Nov 19, 2022
A new coin listing alert bot using Python, Flask, MongoDB, Telegram API and Binance API

Bzzmans New Coin Listing Detection Bot Architecture About Project Work in progress. This bot basically gets new coin listings from Binance using Binan

Eyüp Barlas 21 May 31, 2022
Python API wrapper library for Convex Value API

convex-value-python Python API wrapper library for Convex Value API. Further Links: Convex Value homepage @ConvexValue on Twitter JB on Twitter Authen

Aaron DeVera 2 May 11, 2022
This an API wrapper library for the OpenSea API written in Python 3.

OpenSea NFT API Python 3 wrapper This an API wrapper library for the OpenSea API written in Python 3. The library provides a simplified interface to f

Attila Tóth 159 Dec 26, 2022
YARSAW is an Async Python API Wrapper for the Random Stuff API.

Yet Another Random Stuff API Wrapper - YARSAW YARSAW is an Async Python API Wrapper for the Random Stuff API. This module makes it simpler for you to

Bruce 6 Mar 27, 2022
Python API Client for Twitter API v2

?? Python Client For Twitter API v2 ?? Why Twitter Stream ? Twitter-Stream.py a python API client for Twitter API v2 now supports FilteredStream, Samp

Twitivity 31 Nov 19, 2022
EpikCord.py - This is an API Wrapper for Discord's API for Python

EpikCord.py - This is an API Wrapper for Discord's API for Python! We've decided not to fork discord.py and start completely from scratch for a new, better structuring system!

EpikHost 28 Oct 10, 2022
A simple Python API wrapper for Cloudflare Stream's API.

python-cloudflare-stream A basic Python API wrapper for working with Cloudflare Stream. Arbington.com started off using Cloudflare Stream. We used the

Arbington 3 Sep 8, 2022
Popcorn-time-api - Python API for interacting with the Popcorn Time Servers

Popcorn Time API ?? CONTRIBUTIONS Before doing any contribution read CONTRIBUTIN

Antonio 3 Oct 31, 2022
Telegram PHub Bot using ARQ Api and Pyrogram. This Bot can Download and Send PHub HQ videos in Telegram using ARQ API.

Tg_PHub_Bot Telegram PHub Bot using ARQ Api and Pyrogram. This Bot can Download and Send PHub HQ videos in Telegram using ARQ API. OS Support All linu

TheProgrammerCat 13 Oct 21, 2022