Merge lp:~noise/tanuki-agent/api_example into lp:tanuki-agent

Proposed by Bret Barker
Status: Merged
Approved by: Bret Barker
Approved revision: 82
Merged at revision: 79
Proposed branch: lp:~noise/tanuki-agent/api_example
Merge into: lp:tanuki-agent
Diff against target: 105 lines (+101/-0)
1 file modified
scripts/api_example.py (+101/-0)
To merge this branch: bzr merge lp:~noise/tanuki-agent/api_example
Reviewer Review Type Date Requested Status
Thomi Richards (community) Approve
Review via email: mp+269425@code.launchpad.net

Commit message

basic api_example.py to replace curl in docs for auth'd requests.

To post a comment you must log in.
lp:~noise/tanuki-agent/api_example updated
81. By Bret Barker

minor help text tweak

Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

This looks OK, but I really think we shouldn't be using docopt - it's not in the standard library, it's not as powerful as argparse, and we're supposed to be trying to avoid external dependencies.

Having said that, I clearly lost that argument already with the agent, and this will feed from the same virtualenv, so.. *shrugs*.

review: Approve
Revision history for this message
Bret Barker (noise) wrote :

Thomi - yeah, I wouldn't have used it if we were not already piggybacking on the agent's venv.

Revision history for this message
Facundo Batista (facundo) wrote :

Minor inline comments...

lp:~noise/tanuki-agent/api_example updated
82. By Bret Barker

add -v, -d alias for --data, more clear json err handling

Revision history for this message
Bret Barker (noise) wrote :

Facundo - thanks, added -d alias, tweaked try/except to be more narrow w/comment since it's just to handle "not json" response text.

Pedronis - added -v flag for debug output

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'scripts/api_example.py'
--- scripts/api_example.py 1970-01-01 00:00:00 +0000
+++ scripts/api_example.py 2015-08-27 21:06:07 +0000
@@ -0,0 +1,101 @@
1#!/usr/bin/env python3
2"""
3SPI Api_example - example wrapper for making oauth-signed calls to SPI API endpoints
4
5Usage:
6 api_example.py [options] <configfile> <url>
7
8Options:
9 -h --help Show this screen
10 -d, --data data POST Data
11 -X method HTTP Method
12 -v Verbose debug output
13"""
14
15import json
16import logging
17import sys
18
19from configparser import ConfigParser
20import requests_oauthlib
21
22logging.basicConfig(format='%(asctime)s %(levelname)-5.5s %(name)s %(message)s')
23logger = logging.getLogger(__name__)
24
25try:
26 import docopt
27except:
28 print('This script must be run in the virtualenv, via:')
29 print('. env/bin/activate')
30 print('./scripts/api_example.py')
31 sys.exit(0)
32
33
34class ApiExample(object):
35
36 def __init__(self, arguments):
37 self.config = ConfigParser()
38 self.confpath = arguments['<configfile>']
39 self.method = arguments.get('-X')
40 self.url = arguments.get('<url>')
41 pd = arguments.get('--data')
42 self.post_data = json.loads(pd) if pd else None
43
44 if arguments.get('-v'):
45 logger.setLevel(logging.DEBUG)
46 requests_log = logging.getLogger("requests.packages.urllib3")
47 requests_log.setLevel(logging.DEBUG)
48 requests_log.propagate = True
49 requests_oauthlib_log = logging.getLogger("requests_oauthlib")
50 requests_oauthlib_log.setLevel(logging.DEBUG)
51 else:
52 logger.setLevel(logging.INFO)
53
54 # Load config
55 if self.confpath is not None:
56 self.config.read(self.confpath)
57
58 if 'auth' in self.config:
59 # Here's the substance - we create a requests session
60 # with our oauth credentials (read from config file)
61 self.session = requests_oauthlib.OAuth1Session(
62 self.config.get('auth', 'consumer_key'),
63 client_secret=self.config.get('auth', 'consumer_secret'),
64 resource_owner_key=self.config.get('auth', 'token_key'),
65 resource_owner_secret=self.config.get('auth', 'token_secret'),
66 )
67 else:
68 logger.warning("[auth] config section not found in %s", self.confpath)
69 sys.exit(1)
70
71 def run(self):
72 if self.method is None:
73 if self.post_data is not None:
74 self.method = 'POST'
75 else:
76 self.method = 'GET'
77 logger.debug('%s %s', self.method, self.url)
78 logger.debug('with data: %s', self.post_data)
79
80 if self.method == 'POST':
81 res = self.session.post(self.url, json=self.post_data)
82 elif self.method == 'PUT':
83 res = self.session.put(self.url, json=self.post_data)
84 elif self.method == 'DELETE':
85 res = self.session.delete(self.url)
86 else:
87 res = self.session.get(self.url)
88
89 print('HTTP', res.status_code)
90 try:
91 print(json.dumps(res.json(), indent=2))
92 except ValueError:
93 # response is not json
94 print(res.text)
95 sys.exit(1)
96
97
98if __name__ == '__main__':
99 arguments = docopt.docopt(__doc__, version='SPI Api_example v1')
100 api = ApiExample(arguments)
101 api.run()

Subscribers

People subscribed via source and target branches

to all changes: