def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) if request.method == 'POST': domain = '' try: length = int(request.environ.get('CONTENT_LENGTH', '0')) except ValueError: length = 0 if length != 0: domain = request.environ['wsgi.input'].read(length) else: domain = '/'.join(request.path) """ extract callable that falls back to the included TLD snapshot, no live HTTP fetching """ extract = tldextract.TLDExtract(suffix_list_url=False) ext = extract(domain)._asdict() # ext = tldextract.extract(domain)._asdict() return tools.log_json(ext, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) data = {} try: my_ip = True if request.path[0] == 'ip' else False except Exception: my_ip = False if my_ip: data['ip'] = request.environ.get('REMOTE_ADDR', 0) else: data['API'] = request.version data['ip'] = request.environ.get('REMOTE_ADDR', 0) data['URI'] = request.URI data['method'] = request.method data['city'] = request.environ.get('HTTP_X_APPENGINE_CITY', 0) data['latlong'] = request.environ.get( 'HTTP_X_APPENGINE_CITYLATLONG', 0) data['country'] = request.environ.get( 'HTTP_X_APPENGINE_COUNTRY', 0) return tools.log_json(data, 4)
def lazy_load(self, py_mod, req, stop=False): """ by default the zun_ prefix is appended """ if isinstance(py_mod, list): path = '.'.join([self.prefix + i.lower() for i in py_mod]) name = '%s%s' % (self.prefix, py_mod[-1].lower()) else: path = name = '%s%s' % (self.prefix, py_mod.lower()) req.py_mod = '%s.%s.%s.%s.%s' % ( self.root, req.vroot, req.version, path, name) if req.py_mod in self.resources: req.log.debug(tools.log_json({ 'API': req.version, 'HOST': (req.host, req.vroot), 'URI': req.URI, 'dispatching': (name, req.py_mod), 'rid': req.request_id }, True)) return self.resources[req.py_mod] req.log.debug(tools.log_json({ 'API': req.version, 'HOST': (req.host, req.vroot), 'URI': req.URI, 'loading': (name, req.py_mod), 'rid': req.request_id }, True)) try: __import__(req.py_mod, fromlist=['']) except ImportError as e: if not stop: self.log.debug(tools.log_json({ 'API': req.version, 'ImportError': e, 'URI': req.URI, 'method': req.method, 'py_mod': req.py_mod, 'rid': req.request_id }, True)) return self.lazy_load('_catchall', req, stop=(req.py_mod, e)) raise tools.HTTPException( 501, title="ImportError: %s, %s: %s" % (stop[0], req.py_mod, e), description=stop[1]) module = sys.modules[req.py_mod] resource = module.__dict__['APIResource'] self.resources[req.py_mod] = resource() return self.resources[req.py_mod]
def dispatch(self, request, response): request.log.debug( tools.log_json( {"API": request.version, "Method": request.method, "URI": request.URI, "vroot": request.vroot}, True ) ) return tools.log_json(request.environ, 4)
def __call__(self, environ, start_response): """Handle a WSGI application request. See pep 3333 """ if self.rid and self.rid in environ: request_id = environ[self.rid] else: request_id = str(uuid1()) req = request.Request( self.log, request_id, environ) res = response.Response( self.log, request_id, self._headers.copy(), start_response) body = [] try: body = self.router(req).dispatch(req, res) except tools.HTTPError as e: res.status = e.status if e.headers: res.headers.update(e.headers) if e.display: body.append(e.to_json()) if e.log: self.log.warning(tools.log_json({ 'API': req.version, 'HTTPError': e.status, 'URI': req.URI, 'body': e.to_dict(), 'method': req.method, 'rid': req.request_id }, True)) except Exception as e: res.status = 500 self.log.error(tools.log_json({ 'API': req.version, 'Exception': e, 'URI': req.URI, 'method': req.method, 'rid': req.request_id }, True)) res.send() return body or []
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) return tools.log_json(request.environ, 4)
def dispatch(self, req, res): req.log.info(tools.log_json({ 'API': req.version, 'URI': req.URI, 'rid': req.request_id, 'in': 'dispatch', 'thread': req.environ.get('thread', '-'), })) res.headers.update(self.headers) res.body = tools.log_json(req.environ, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) data = {} if request.environ.get('CONTENT_TYPE', '').startswith('multipart'): data['files'] = True return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) data = {} data['URI'] = request.URI data['py_mod'] = request.py_mod data['path'] = request.path return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.info(tools.log_json({ 'API': request.version, 'URI': request.URI, 'rid': request.request_id, 'in': 'dispatch', 'thread': request.environ.get('thread', '-'), 'thread_env': request.environ.get('thread', '-') })) response.headers.update(self.headers) return tools.log_json(request.environ)
def register_routes(self, routes): """compile regex pattern for routes per vroot :param routes: { 'vroot': tuple(regex, py_mod, methods). } """ for vroot, routes in routes.items(): gen = (route for route in routes if isinstance(route, tuple)) vroot = vroot.replace('.', '_') self.routes[vroot] = [] for route in gen: regex, module = route[:2] methods = ['ALL'] if len(route) > 2: methods = [x.strip().upper() for x in route[2].split(',') if x] if regex.startswith('^'): self.routes[vroot].append( (re.compile(r'%s' % regex), module, methods)) else: self.routes[vroot].append( (re.compile(r'^%s$' % regex), module, methods)) self.log.debug(tools.log_json({ 'vroot': vroot, "regex": regex, "py_mod": module, "methods": methods }, True))
def dispatch(self, request, response): data = { 'URI': request.URI, 'resource': request.resource, 'path': request.path, } return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) data = {} try: data['status code'] = codes[int(request.path[0], 0)] except Exception as _: data['status code'] = 'not found' data['URI'] = request.URI return tools.log_json(data, 4)
def dispatch(self, request, response): data = {} data['URI'] = request.URI data['py_mod'] = request.py_mod data['path'] = request.path return tools.log_json(data, 4)
def get_status(self): try: status = int(self.status) except Exception as e: self.log.error(tools.log_json({"no status": e, "status": self.status})) status = 500 try: if status in http_status_codes.codes: status = http_status_codes.codes[status] else: status = http_status_codes.generic_reasons[status // 100] except Exception as e: self.log.error(tools.log_json({"bad status": e, "status": status})) status = "500 Internal Server Error" return status
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'URI': request.URI, 'method': request.method, 'vroot': request.vroot }, True)) data = {} data['about'] = ("Hi %s, I am zunzuncito a micro-framework for creating" " REST API's, you can read more about me in: " "www.zunzun.io") % request.environ.get('REMOTE_ADDR', 0) data['Request-ID'] = request.request_id data['URI'] = request.URI data['Method'] = request.method return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'path': request.path, 'vroot': request.vroot }, True)) return __name__
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) if request.path: response.status = int(request.path[0]) return response.request_id
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) hash_type = request.resource if request.method == 'POST': string = '' try: length = int(request.environ.get('CONTENT_LENGTH', '0')) except ValueError: length = 0 if length != 0: string = request.environ['wsgi.input'].read(length) else: string = '/'.join(request.path) data = {} data['type'] = hash_type data['string'] = string if hash_type == 'md5': data['hash'] = hashlib.md5(string).hexdigest() elif hash_type == 'sha1': data['hash'] = hashlib.sha1(string).hexdigest() elif hash_type == 'sha256': data['hash'] = hashlib.sha256(string).hexdigest() elif hash_type == 'sha512': data['hash'] = hashlib.sha512(string).hexdigest() return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'URI': request.URI, 'method': request.method, 'vroot': request.vroot }, True)) data = {} data['about'] = "Hi %s, I am %s on %s" % ( request.environ.get('REMOTE_ADDR', 0), request.host, request.vroot) data['Method'] = request.method data['Request-ID'] = request.request_id data['URI'] = request.URI data['host'] = request.host data['vroot'] = request.vroot return tools.log_json(data, 4)
def dispatch(self, request, response): request.log.debug( tools.log_json( {"API": request.version, "Method": request.method, "URI": request.URI, "vroot": request.vroot}, True ) ) try: name = request.path[0] except: raise tools.HTTPException(400) if name != "foo": raise tools.HTTPException( 406, title="exeption example", description="name must be foo", code="my-custom-code", display=True ) return __name__
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) response.headers.update(self.headers) """ calls start_response """ response.send() t = gevent.spawn(long_task) t.join() yield "sleep 1 second.<br/>" gevent.sleep(1) yield "sleep 3 seconds...<br/>" gevent.sleep(3) yield "done.<br/>getting some ips...<br/>" urls = [ 'www.google.com', 'www.example.com', 'www.python.org', 'zunzun.io'] jobs = [gevent.spawn(gevent.socket.gethostbyname, url) for url in urls] gevent.joinall(jobs, timeout=2) for j in jobs: yield "ip = %s<br/>" % j.value gevent.spawn(bg_task)
def __init__(self, root, versions=None, hosts=None, routes=None, prefix='zun_', rid=None, debug=False): self._headers = tools.CaseInsensitiveDict() self.allowed_URI_chars = re.compile(r'^[\w-]+$') self.host = '*' self.hosts = {'*': 'default'} if isinstance(hosts, dict): self.hosts = hosts self.prefix = prefix self.resources = {} self.rid = rid self.root = root self.routes = {} self.versions = ['v0', 'v1'] self.version = self.versions[0] self.vroot = 'default' if versions and isinstance(versions, list): versions = tuple( m.group(0) for m in ( self.allowed_URI_chars.search(v) for v in map( str, versions)) if m) if versions: self.versions = versions else: raise Exception('Versions missing') self.log = logging.getLogger() if not self.log.handlers: self.log.addHandler(logging.StreamHandler()) self.log.setLevel('DEBUG' if debug else 'INFO') self.log.debug(tools.log_json(locals())) """ register / compile the routes regex """ if isinstance(routes, dict): self.register_routes(routes)
def dispatch(self, request, response): request.log.debug(tools.log_json({ 'API': request.version, 'Method': request.method, 'URI': request.URI, 'vroot': request.vroot }, True)) b = request.environ.get('HTTP_USER_AGENT') for k, v in request.environ.items(): # convert all string values to unicode values and replace # malformed data with a suitable # replacement marker. if isinstance(v, str): request.environ[k] = v.decode('utf-8', 'replace') a = request.environ.get('HTTP_USER_AGENT') return str(type(b)) + str(type(a))
def dispatch(self, request, response): req = Request(request.environ) # to get a post param # field = req.POST['field'] data = {} data["req-GET"] = req.GET data["req-POST"] = req.POST data["req-application_url"] = req.application_url data["req-body"] = req.body data["req-content_type"] = req.content_type data["req-cookies"] = req.cookies data["req-method"] = req.method data["req-params"] = req.params data["req-path"] = req.path data["req-path_info"] = req.path_info data["req-path_qs"] = req.path_qs data["req-path_url"] = req.path_url data["req-query_string"] = req.query_string data["req-script_name"] = req.script_name data["req-url"] = req.url return tools.log_json(data, 4)
def dispatch(self, request, response): return tools.log_json(request.__dict__, 4)
def dispatch(self, request, response): return tools.log_json(request.environ, 4)
def router(self, req): """ check if the URI is versioned (/v1/resource/...) defaults to the first version in versions list (default to v0). """ req.version = self.versions[0] for version in self.versions: if req.URI.lower().startswith('/%s' % version): req.version = version """ if URI is versioned, remove the version '/v0' from URI the + 1 if for the starting '/' in the URI """ req.URI = req.URI[len(req.version) + 1:] break """ find a python module (py_mod) to handle the request per host """ py_mod = False if req.host in self.hosts.keys(): req.vroot = self.hosts[req.host] else: for host in self.hosts.keys(): if re.match(r'^\*\.', host): domain = r'^(?:[^./@]+\.)*%s$' % ( host.replace('*.', '').replace('.', r'\.')) if re.match(domain, host): req.vroot = self.hosts[host] break req.log.debug(tools.log_json({ 'API': req.version, 'HOST': (req.host, req.vroot), 'URI': req.URI, 'rid': req.request_id, 'versions': self.versions }, True)) """ try to match any supplied routes (regex match) only if the current host has defined routes t[0] = r - regex t[1] = p - py_mod t[2] = h - HTTP methods """ if req.vroot in self.routes: filterf = lambda t: any(i in (req.method.upper(), 'ALL') for i in t[2]) for r, p, h in filter(filterf, self.routes[req.vroot]): match = r.match(req.URI) if match: py_mod = p req.log.debug(tools.log_json({ 'API': req.version, 'HOST': (req.host, req.vroot), 'methods': h, 'regex_match': (r.pattern, req.URI), 'rid': req.request_id }, True)) break """ get the API resource and path from URI api_resource/path """ components = [x.strip() for x in req.URI.split('?')[0].split('/') if x.strip()] req.resource = ''.join(components[:1]) req.path = components[1:] if not py_mod: """ URI 2 mod: /add/user/ -> zun_add/zun_user/zun_user.py """ if len(req.path) >= 1 and req.URI.endswith('/'): if self.allowed_URI_chars.match(''.join(components)): py_mod = components elif len(req.path) > 1: if self.allowed_URI_chars.match(''.join(components[:-1])): py_mod = components[:-1] else: py_mod = 'default' if not components else req.resource return self.lazy_load(py_mod, req)
def dispatch(self, request, response): try: temp_name = request.path[0] except: raise tools.HTTPException(400) """rfc2616-sec14.html see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html see http://www.grid.net.ru/nginx/resumable_uploads.en.html """ content_range = request.environ.get('HTTP_CONTENT_RANGE', 0) length = int(request.environ.get('CONTENT_LENGTH', 0)) if content_range: content_range = content_range.split()[1].split('/') index, offset = [int(x) for x in content_range[0].split('-')] total_size = int(content_range[1]) if length: chunk_size = length elif offset > index: chunk_size = (offset - index) + 1 elif total_size: chunk_size = total_size else: raise tools.HTTPException(416) elif length: chunk_size = total_size = length index = 0 offset = 0 else: raise tools.HTTPException(400) stream = request.environ['wsgi.input'] body = [] try: temp_file = os.path.join( os.path.dirname('/tmp/test_upload/'), temp_name) with open(temp_file, 'a+b') as f: original_file_size = f.tell() f.seek(index) f.truncate() bytes_to_write = chunk_size while chunk_size > 0: # buffer size chunk = stream.read(min(chunk_size, 1 << 13)) if not chunk: break f.write(chunk) chunk_size -= len(chunk) f.flush() bytes_written = f.tell() - index if bytes_written != bytes_to_write: f.truncate(original_file_size) f.close() raise tools.HTTPException(416) if os.stat(temp_file).st_size == total_size: response.status = 200 else: response.status = 201 body.append('%d-%d/%d' % (index, offset, total_size)) request.log.info(tools.log_json({ 'index': index, 'offset': offset, 'size': total_size, 'status': response.status, 'temp_file': temp_file }, True)) return body except IOError: raise tools.HTTPException( 500, title="upload directory [ %s ]doesn't exist" % temp_file, display=True)