1
2
3
4
5
6
7 try:
8 from IPython.Shell import IPShellEmbed
9 except ImportError:
10 raise ImportError('IPython (http://pypi.python.org/pypi/ipython) ' +\
11 'is required.')
12
13 try:
14 import webob
15 except ImportError:
16 raise ImportError('webob (http://pythonpaste.org/webob/) is required.')
17
18 from restkit import __version__
19 from restkit.console import common_indent, json
20 from restkit.contrib.webob_api import Request as BaseRequest
21 from webob import Response as BaseResponse
22 from StringIO import StringIO
23 import IPython
24
27 return '<Stream(%s)>' % self.len
28
29
38 return '<JSON(%s)>' % self.__value
39
40
43 if self.content_length < 200 and skip_body:
44 skip_body = False
45 return BaseResponse.__str__(self, skip_body=skip_body)
48
49
51 ResponseClass = Response
53 url = self.url
54 stream = None
55 for a in args:
56 if isinstance(a, Stream):
57 stream = a
58 a.seek(0)
59 continue
60 elif isinstance(a, basestring):
61 if a.startswith('http'):
62 url = a
63 elif a.startswith('/'):
64 url = a
65
66 self.set_url(url)
67
68 if stream:
69 self.body_file = stream
70 self.content_length = stream.len
71 if self.method == 'GET' and kwargs:
72 for k, v in kwargs.items():
73 self.GET[k] = v
74 elif self.method == 'POST' and kwargs:
75 for k, v in kwargs.items():
76 self.GET[k] = v
77 return BaseRequest.get_response(self)
78
80 if self.content_length < 200 and skip_body:
81 skip_body = False
82 return BaseRequest.__str__(self, skip_body=skip_body)
83
86
87
88 -class ContentTypes(object):
89 _values = {}
91 return '<%s(%s)>' % (self.__class__.__name__, sorted(self._values))
93 return '\n'.join(['%-20.20s: %s' % h for h in \
94 sorted(self._value.items())])
95
96
97 ctypes = ContentTypes()
98 for k in common_indent:
99 attr = k.replace('/', '_').replace('+', '_')
100 ctypes._values[attr] = attr
101 ctypes.__dict__[attr] = k
102 del k, attr
103
104
105 -class API(property):
107 return IPython.ipapi.get() or __IPYTHON__.api
108
109
110 -class Shell(IPShellEmbed):
112 argv = [
113 '-prompt_in1','\C_Blue\#) \C_Greenrestcli\$ ',
114 ]
115 IPShellEmbed.__init__(self,argv,banner='restkit shell %s' % __version__,
116 exit_msg=None,rc_override=None,
117 user_ns=kwargs)
118
119
121 api = API()
122 methods = dict(
123 get='[req|url|path_info], **query_string',
124 post='[req|url|path_info], [Stream()|**query_string_body]',
125 head='[req|url|path_info], **query_string',
126 put='[req|url|path_info], stream',
127 delete='[req|url|path_info]')
128
129 - def __init__(self, url='/', options=None, **kwargs):
130 self.options = options
131 self.url = url or '/'
132 self.ns = {}
133 ipshell = Shell(self.ns)
134 self.update_ns(self.ns)
135 self.help()
136 ipshell(header='', global_ns={}, local_ns={})
137
139 for k in self.methods:
140 ns[k] = self.request_meth(k)
141 stream = None
142 headers = {}
143 if self.options:
144 if self.options.input:
145 stream = Stream(open(self.options.input).read())
146 if self.options.headers:
147 for header in self.options.headers:
148 try:
149 k, v = header.split(':')
150 headers.append((k, v))
151 except ValueError:
152 pass
153 req = Request.blank('/')
154 req._client = self
155 del req.content_type
156 if stream:
157 req.body_file = stream
158 req.headers = headers
159 req.set_url(self.url)
160 ns.update(
161 Request=Request,
162 Response=Response,
163 Stream=Stream,
164 req=req,
165 stream=stream,
166 ctypes=ctypes,
167 )
168 if json:
169 ns['JSON'] = JSON
170
172 def req(*args, **kwargs):
173 resp = self.request(k.upper(), *args, **kwargs)
174 self.api.to_user_ns(dict(resp=resp))
175 print resp
176 return resp
177 req.func_name = k
178 req.__name__ = k
179 req.__doc__ = """send a HTTP %s""" % k.upper()
180 return req
181
182 - def request(self, meth, *args, **kwargs):
183 """forward to restkit.request"""
184 req = None
185 for a in args:
186 if isinstance(a, Request):
187 req = a
188 args = [a for a in args if a is not req]
189 break
190 if req is None:
191 req = self.api.user_ns.get('req')
192 if not isinstance(req, Request):
193 req = Request.blank('/')
194 del req.content_type
195 req.method = meth
196 req.set_url(self.url)
197 resp = req.get_response(*args, **kwargs)
198 self.url = req.url
199 return resp
200
202 ns = self.ns.copy()
203 methods = ''
204 for k in sorted(self.methods):
205 args = self.methods[k]
206 doc = ' >>> %s(%s)' % (k, args)
207 methods += '%-65.65s # send a HTTP %s\n' % (doc, k)
208 ns['methods'] = methods
209 print HELP.strip() % ns
210 print ''
211
213 return '<shellclient>'
214
215
216 -def main(*args, **kwargs):
217 for a in args:
218 if a.startswith('http://'):
219 kwargs['url'] = a
220 ShellClient(**kwargs)
221
222
223 HELP = """
224 restkit shell
225 =============
226
227 HTTP Methods
228 ------------
229
230 %(methods)s
231 Helpers
232 -------
233
234 >>> req # request to play with. By default http methods will use this one
235 %(req)r
236
237 >>> stream # Stream() instance if you specified a -i in command line
238 %(stream)r
239
240 >>> ctypes # Content-Types helper with headers properties
241 %(ctypes)r
242 """
243
244 if __name__ == '__main__':
245 import sys
246 main(*sys.argv[1:])
247