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   
  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   
25 -class Stream(StringIO):
26 - def __repr__(self):
27 return '<Stream(%s)>' % self.len
28 29
30 -class JSON(Stream):
31 - def __init__(self, value):
32 self.__value = value 33 if json: 34 Stream.__init__(self, json.dumps(value)) 35 else: 36 Stream.__init__(self, value)
37 - def __repr__(self):
38 return '<JSON(%s)>' % self.__value
39 40
41 -class Response(BaseResponse):
42 - def __str__(self, skip_body=True):
43 if self.content_length < 200 and skip_body: 44 skip_body = False 45 return BaseResponse.__str__(self, skip_body=skip_body)
46 - def __call__(self):
47 print self
48 49
50 -class Request(BaseRequest):
51 ResponseClass = Response
52 - def get_response(self, *args, **kwargs):
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
79 - def __str__(self, skip_body=True):
80 if self.content_length < 200 and skip_body: 81 skip_body = False 82 return BaseRequest.__str__(self, skip_body=skip_body)
83
84 - def __call__(self):
85 print self
86 87
88 -class ContentTypes(object):
89 _values = {}
90 - def __repr__(self):
91 return '<%s(%s)>' % (self.__class__.__name__, sorted(self._values))
92 - def __str__(self):
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):
106 - def __get__(self, *args):
107 return IPython.ipapi.get() or __IPYTHON__.api
108 109
110 -class Shell(IPShellEmbed):
111 - def __init__(self, kwargs):
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
120 -class ShellClient(object):
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
138 - def update_ns(self, ns):
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
171 - def request_meth(self, k):
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
201 - def help(self):
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
212 - def __repr__(self):
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