Package restkit :: Package contrib :: Module ipython_shell
[hide private]
[frames] | no frames]

Source Code for Module restkit.contrib.ipython_shell

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of restkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  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   
28 -class Stream(StringIO):
29 - def __repr__(self):
30 return '<Stream(%s)>' % self.len
31 32
33 -class JSON(Stream):
34 - def __init__(self, value):
35 self.__value = value 36 if json: 37 Stream.__init__(self, json.dumps(value)) 38 else: 39 Stream.__init__(self, value)
40 - def __repr__(self):
41 return '<JSON(%s)>' % self.__value
42 43
44 -class Response(BaseResponse):
45 - def __str__(self, skip_body=True):
46 if self.content_length < 200 and skip_body: 47 skip_body = False 48 return BaseResponse.__str__(self, skip_body=skip_body)
49 - def __call__(self):
50 print self
51 52
53 -class Request(BaseRequest):
54 ResponseClass = Response
55 - def get_response(self, *args, **kwargs):
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
82 - def __str__(self, skip_body=True):
83 if self.content_length < 200 and skip_body: 84 skip_body = False 85 return BaseRequest.__str__(self, skip_body=skip_body)
86
87 - def __call__(self):
88 print self
89 90
91 -class ContentTypes(object):
92 _values = {}
93 - def __repr__(self):
94 return '<%s(%s)>' % (self.__class__.__name__, sorted(self._values))
95 - def __str__(self):
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):
109 - def __get__(self, *args):
110 return IPython.ipapi.get() or __IPYTHON__.api
111 112
113 -class Shell(IPShellEmbed):
114 - def __init__(self, kwargs):
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
123 -class ShellClient(object):
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
141 - def update_ns(self, ns):
142 for k in self.methods: 143 ns[k] = self.request_meth(k) 144 stream = None 145 headers = {} 146 if self.options: 147 if self.options.input: 148 stream = Stream(open(self.options.input).read()) 149 if self.options.headers: 150 for header in self.options.headers: 151 try: 152 k, v = header.split(':') 153 headers.append((k, v)) 154 except ValueError: 155 pass 156 req = Request.blank('/') 157 req._client = self 158 del req.content_type 159 if stream: 160 req.body_file = stream 161 req.headers = headers 162 req.set_url(self.url) 163 ns.update( 164 Request=Request, 165 Response=Response, 166 Stream=Stream, 167 req=req, 168 stream=stream, 169 ctypes=ctypes, 170 ) 171 if json: 172 ns['JSON'] = JSON
173
174 - def request_meth(self, k):
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
204 - def help(self):
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
215 - def __repr__(self):
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