title: Getting an Oauth 2.0 API signed request to work in Python/Django
body: <p>I'm trying to get a signed Oauth 2.0 to work in python to feed a Django app.
  Here is the closest that I got, using this code:</p>
  
  <pre><code>from oauth_hook import OAuthHook
  import requests
  import json
  
  OAuthHook.consumer_key = "key"
  OAuthHook.consumer_secret = "secret"
  oauth_hook = OAuthHook("access_token", "", header_auth=True)
  
  client = requests.session(hooks={'pre_request': oauth_hook})
  response = client.get('https://demo.checkfront.com/api/2/booking/form/')
  results = json.loads(response.content)
  
  print response.content
  </code></pre>
  
  <p>But all I got is this:</p>
  
  <pre><code>{"error":"invalid_request","error_description":"Malformed auth header"}
  </code></pre>
  
  <p>Consider that from the API provider I got:</p>
  
  <ul>
  <li>Consumer Key</li>
  <li>Consumer Secret</li>
  <li>Authorize Token URL</li>
  <li>AccessToken Url</li>
  <li>Access Token</li>
  <li>Refresh Token</li>
  </ul>
  
  <p>The process works in PHP, this is the code</p>
  
  <pre><code>&lt;?php
  
  include('../lib/CheckfrontAPI.php');
  
  class Checkfront extends CheckfrontAPI {
  
      public $tmp_file = '.checkfront_oauth';
  
      public function __construct($data) {
          parent::__construct($data);
          session_start();
      }
  
  
      final protected function store($data=array()) {
          $tmp_file = sys_get_temp_dir() . DIRECTORY_SEPARATOR. $this-&gt;tmp_file;
          if(count($data)  ) {
              file_put_contents($tmp_file,json_encode($data,true));
          } elseif(is_file($tmp_file)) {
              $data = json_decode(trim(file_get_contents($tmp_file)),true);
          }
          return $data;
      }
  
      public function session($session_id,$data=array()) {
          $_SESSION['checkfront']['session_id'] = $session_id;
      }
  }
  
  
  $Checkfront = new Checkfront(
      array(
          'host'=&gt;'MY_ACCOUNT.checkfront.com', 
          'consumer_key'  =&gt; 'consumer_key',  
          'consumer_secret' =&gt; 'consumer_secret',  
          'redirect_uri'=&gt;'oob', 
          'refresh_token' =&gt; 'refresh_token',  
      )
  );
  
  
  if($data = $Checkfront-&gt;cql('select * from status')) {
      print_r($data);
  
  } elseif($Checkfront-&gt;error) {
      //
      print "Error: \n" . var_export($Checkfront-&gt;error,true);
  }
  ?&gt;
  </code></pre>
  
  <p>and this is the CheckfrontAPI.php code:</p>
  
  <pre><code>&lt;?php
  /**
   * Checkfront SDK 
   * PHP 5 
   *
   * @package     CheckfrontAPI
   * @author      Checkfront &lt;code@checkfront.com&gt;
   * @copyright   2008-2012 Checkfront Inc 
   * @license     http://opensource.org/licenses/bsd-license.php New BSD License
   * @link        http://www.checkfront.com/developers/api/
   * @link        https://github.com/Checkfront/PHP-SDK
   *
   *
   */
  
  
  /*
   * @access public
   * @package Checkfront
  */
  abstract class CheckfrontAPI {
  
      protected $sdk_version = '1.1';
      protected $api_version = '2';
  
      public $error = array();
      private $api_timeout = '30';
  
      private $host = "";
      public $consumer_key = "";
      private $consumer_secret= "";
      private $access_token = '';
      private $refresh_token = '';
  
      private $server_token = ''; // legacy 
  
      private $api_id = 'UA';
  
      private $session_id = '';
  
      abstract protected function store($data);
      abstract public function session($session_id,$data);
  
      function __construct($config=array(),$session_id='') {
          $this-&gt;host = $config['host'];
          $this-&gt;consumer_key = $config['consumer_key'];
          $this-&gt;consumer_secret = $config['consumer_secret'];
          $this-&gt;redirect_uri = $config['redirect_uri'];
          $this-&gt;oauth_url = "https://{$this-&gt;host}/oauth";
          $this-&gt;api_url = "https://{$this-&gt;host}/api/{$this-&gt;api_version}";
          $this-&gt;app_id = $config['app_id'];
          $this-&gt;client_ip = $config['client_ip'];
          $this-&gt;refresh_token = $config['refresh_token'];
          $this-&gt;session_id = $session_id;
          $this-&gt;account_id = $config['account_id'];
          $this-&gt;server_token = $config['server_token'];
          $this-&gt;tokens();
      }
  
      /**
       * Check and refresh access token if needed.
       *
       * @return bool 
       */
      private function init() {
          if(isset($this-&gt;refresh_token)) {
              if(!$this-&gt;access_token or $this-&gt;expire_token &lt; time()) {
                  $this-&gt;refresh_token();
              }
          }
      }
  
  
      /**
       * API call via curl
       *
       * @param string $url 
       * @param array $data post / get data
       *
       * @return array json parsed response array
       */
      final private function call($url,$data=array(),$type='') {
  
  
          $ch = curl_init();
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_USERAGENT, "Checkfront PHP/SDK {$this-&gt;sdk_version} ({$this-&gt;app_id})");
          curl_setopt($ch, CURLOPT_HEADER, 0);
  
          // set custom headers
          $headers = array('Accept: application/json');
  
          // legacy
          if($this-&gt;server_token) {
              $headers[] = "X-Server-Token: {$this-&gt;server_token}";
          }
  
          if($this-&gt;client_ip) {
              $headers[] = "X-Forwarded-For: {$this-&gt;client_ip}";
          } else {
              $headers[] = "X-Forwarded-For: {$_SERVER['REMOTE_ADDR']}";
          }
  
          if($this-&gt;account_id) {
              $headers[] = "X-On-Behalf: {$this-&gt;account_id}";
          }
  
          if($this-&gt;access_token) {
              $headers[] = "Authorization: BEARER {$this-&gt;access_token}";
          }
  
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  
          // pass session id
          // @see session_create()
          if($this-&gt;session_id) {
              curl_setopt($ch, CURLOPT_COOKIESESSION, true);
              curl_setopt($ch, CURLOPT_COOKIE, "session_id={$this-&gt;session_id}");
          }
  
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
          curl_setopt($ch, CURLOPT_TIMEOUT, $this-&gt;api_timeout);
  
          if($data) {
              curl_setopt($ch, CURLOPT_POST, true);
              if(is_array($data)) {
                  // needs to encode to support assocative arrays
                  curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
              } else {
                  curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
              }
          } else {
              curl_setopt($ch, CURLOPT_HTTPGET, true);
          }
  
  
          if($response = curl_exec($ch)) {
              curl_close($ch);
              $response = json_decode($response,true);
              if($response['error']) {
                  $this-&gt;error = array('id'=&gt;$response['error'],'msg'=&gt;$response['error_description']);
                  return false;
              } else {
                  return $response;
              }
  
          } else {
              $this-&gt;error = array('curl'=&gt;curl_error($ch));
          }
      }
  
      /**
       * Set the session
       *
       * @param string session_id
       * @param array $data session
       *
       * @return bool
      */
      final public function set_session($session_id,$data=array()) {
          $this-&gt;session_id = $session_id;
          return $this-&gt;session($session_id,$data);
      }
  
      /**
       * API request
       *
       * @param string $url 
       * @param array $data post / get data
       *
       * @return array json parsed response array
       */
      final function api($path,$data=array()) {
  
          $this-&gt;init();
  
          $url .= $this-&gt;api_url . '/' . $path;
          if($response = $this-&gt;call($url,$data)) {
              if($response['session_id']) {
                  $this-&gt;session($response['session_id']);
              }
              return $response;
          } else {
              return false;
          }
      }
  
  
      /**
       * Authorize request
       *
       * @param bool $redirect automatically send the redirect header
       *
       * @return mixed Returns if $redirect is true returns bool, otherwise returns the authorization URL
       * @link http://www.checkfront.com/developers/api/#oauth
       */
      final public function authorize($redirect=1) {
          $args = array(
              'type'=&gt;'web_server',
              'client_id'=&gt;$this-&gt;consumer_key,
              'redirect_uri'=&gt;$this-&gt;oauth_redirect_uri,
              'response_type'=&gt;'code',
          );
          $url = $this-&gt;oauth_url . '/?' . http_build_query($args);
  
          if($redirect) {
              return header("Location: {$url}");
          } else {
              return $url;
          }
      }
  
  
      /**
       * Fetch access token
       * @param string $code returned from Checkfront::authorize()
       * @return mixed 
       */
      final public function fetch_token($code) {
  
          $data = array(
              'type'=&gt;'web_server',
              'client_id'=&gt;$this-&gt;consumer_key,
              'grant_type' =&gt; 'authorization_code',
              'client_secret' =&gt; $this-&gt;consumer_secret,
              'redirect_uri'=&gt;$this-&gt;redirect_uri,
              'code'=&gt;$code,
          );
  
  
          $url = $this-&gt;oauth_url . '/token/';
          if($tokens = $this-&gt;call($url,$data)) {
              if($tokens['error']) {
                  return false;
              } else {
                  $this-&gt;tokens($tokens);
                  return true;
              }
          }
      }
  
      /**
       * Refresh access token
       * @param string $code returned from Checkfront::authorize()
       * @return mixed 
       */
      final private function refresh_token() {
  
          $data = array(
              'type'=&gt;'web_server',
              'client_id'=&gt;$this-&gt;consumer_key,
              'grant_type' =&gt; 'refresh_token',
              'client_secret' =&gt; $this-&gt;consumer_secret,
              'redirect_uri'=&gt;$this-&gt;redirect_uri,
              'refresh_token'=&gt;$this-&gt;refresh_token,
          );
  
          $url = $this-&gt;oauth_url . '/token/';
          if($tokens = $this-&gt;call($url,$data)) {
  
              if($tokens['error']) {
                  return false;
              } else {
                  $this-&gt;tokens($tokens);
                  return true;
              }
          }
      }
  
  
      /**
       * Get expire token datetime
       *
       * @param integer $time seconds to expore
       *
       * @return integer unix date - expire dirft. 
       */
      private function expire_token($time) {
          return time() + $time - $this-&gt;expire_drift;
      }
  
  
      /**
       * Set access token  
       *
       * @param array $data Token data (access_token,refresh_token,expire_token)
       *
       * @return mixed 
       */
      private function tokens($data=array()) {
  
          if($data) {
              if($data['expires_in']) {
                  $data['expire_token'] = $this-&gt;expire_token($data['expire_in']);
              }
              $this-&gt;store(
                  array(
                      'refresh_token'=&gt;$data['refresh_token'],
                      'access_token'=&gt;$data['access_token'],
                      'expire_token'=&gt;$data['expire_token'],
                      'updated'=&gt;time()
                  )
              );
          } else {
              $data = $this-&gt;store();
          }
  
          if(isset($data['access_token'])) $this-&gt;access_token  = $data['access_token'];
          if(isset($data['refresh_token'])) $this-&gt;refresh_token = $data['refresh_token'];
          if(isset($data['expire_token'])) $this-&gt;expire_token = $data['expire_token'];
      }
  
  
      /**
       * CQL Query
       * @param sting $q SQL style query 
       * @return mixed sql results, or false on failure
       * @link http://www.checkfront.com/developers/api-cql/
       */
      final public function cql($q) {
          $this-&gt;init();
          if($data = $this-&gt;get('cql',array('q'=&gt;$q))) {
              return $data;
          } else {
              return false;
          }
      }
  
  
      /**
       * API GET request
       *
       * @param string $url 
       * @param array $ags get data
       *
       * @return array json parsed response array
       */
      final public function get($path, $data=array()) {
          if($data) $path .= '/?'  . http_build_query($data);
          if($response = $this-&gt;api($path)) {
              return $response;
          } else {
              return false;
          }
      }
  
  
      /**
       * API PUT request
       *
       * @param string $url 
       * @param array $ags put data
       *
       * @return array json parsed response array
       */
      final public function put($path,$data) {
          return $this-&gt;api($path,$data,'put');
      }
  
  
      /**
       * API DELETE request
       *
       * @param string $url 
       *
       * @return array json parsed response array
       */
      final public function delete($path,$data) {
          return $this-&gt;api($path,$data,'delete');
      }
  
  
      /**
       * API POST
       *
       * @param string $path uri path
       * @param array $data post data
       *
       * @return mixed 
       */
      final public function post($path,$data) {
          return $this-&gt;api($path,$data);
      }
  
  
      public function session_clear() {
          $this-&gt;session_id = 0; 
      }
  }
  ?&gt;
  </code></pre>
  
  <p>How can I get this API calls signed with Oauth 2.0 to work under python/django?</p>