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