class Router(Singleton): """ Router implements unique hierarhical url mapping. Pass dictionary with mapping of regex and controller. """ def __init__(self, options): self.options = options self.eventer = Eventer() self.add_urls(self.options["urls"], False) if "templates_path" in self.options["views"]: tps = [] for tp in self.options["views"]["templates_path"]: tps.append(PackageLoader(tp, "")) self.options["views"]["templates_environment"] = Environment( loader=ChoiceLoader(tps), extensions=self.options["views"]["templates_extensions"] ) def add_urls(self, urls, merge=True): urls = Dict.flat_dict(urls) new_urls = [] for k, v in urls.iteritems(): if k[len(k) - 2] == "/": k = k[: len(k) - 2] + k[len(k) - 1] k = re.compile(k) if inspect.isclass(v): new_urls.append((k, v())) else: new_urls.append((k, v)) if merge: self.options["urls"] = self.options["urls"] + new_urls else: self.options["urls"] = new_urls def route(self, request): for (re_url, controller) in self.options["urls"]: path = request.path.lower() if path[len(path) - 1] == "/": path = path.rstrip("/") mtch = re_url.match(path) if mtch: request.params = mtch.groupdict() try: self.eventer.publish("BeforeControllerAction", request) # check if controller has method for all requests if hasattr(controller, "process") and inspect.ismethod(getattr(controller, "process")): action = getattr(controller, "process") else: action = getattr(controller, request.method.lower()) response = action(request) self.eventer.publish("AfterControllerAction", request, response) if not response: break return response except HTTPException, e: return self.get_err_page(e) except Exception, e: return self.get_err_page(InternalServerError(description=traceback.format_exc()))
def __init__(self, options): self.options = options self.logger = logging.getLogger(__name__) self.eventer = Eventer() self.add_urls(self.options["urls"], False) if "templates_path" in self.options["views"]: tps = [] for tp in self.options["views"]["templates_path"]: tps.append(PackageLoader(tp, "")) self.options["views"]["templates_environment"] = Environment(loader=ChoiceLoader(tps), extensions=self.options["views"]["templates_extensions"])
def get(self, request): #publish some event eventer = Eventer() eventer.publish("some event", self) if not "foo" in request.session: request.session["foo"] = 0 request.session["foo"] += 1 blog = Blog(name="super blog", creator="Stas") if not Entry.get_by(title="super post"): entry = Entry(title="super post", body="saifjo", blog=blog) session.commit() print Entry.query.all() return TemplateResponse("view.html", { "foo": request.session["foo"], "users": [{"url": "google.com", "username": "******"}], "blog": blog })
def init_eventer(self): self.eventer = Eventer(self.options["events"])
class Application(Singleton): """ Main class of your application. Pass options to constructor and all subsystems(eventer, router) will be configured. """ def __init__(self, options): self.init_options(options) self.init_eventer() self.init_router() self.init_templater() self.eventer.publish("BeforeDatabaseEngineConfiguration", self) self.init_db() self.eventer.publish("AfterDatabaseEngineConfiguration", self) self.init_session() self.eventer.publish("BeforeInitStatic", self) self.init_static() self.eventer.publish("AfterInitStatic", self) self.eventer.publish("BeforeInitServer", self) self.init_server() self.eventer.publish("AfterInitServer", self) self.eventer.publish("BeforeApplicationStarted", self) def init_options(self, options): logging.basicConfig(level=logging.CRITICAL) default_options = { "application": { "address": "127.0.0.1", "port": 8080, "system": { "log": None } }, "urls": {}, "views": { "templates_path": [], "templates_extensions": ["compressinja.html.HtmlCompressor", "jinja2.ext.i18n"], "static_path": [], "static_not_compile": [], "static_build": True, 'session_type': "cookie", "session_auto": True, 'session_cookie_expires': True, 'session_encrypt_key': 'sldk24j0jf09w0jfg24', 'session_validate_key': ';l[pfghopkqeq1234,fs' }, "events": {} } self.options = Dict.merge(default_options, options) def init_eventer(self): self.eventer = Eventer(self.options["events"]) def init_router(self): self.router = Router(self.options) def init_templater(self): self.templater = Templater(self) def init_static(self): static_builder = None self.add_static( self.options["views"]["static_path"], not_compile=self.options["views"]["static_not_compile"], merge=False, build=self.options["views"]["static_build"]) def add_static(self, sps, not_compile=[], url_path="/", merge=True, build=True): static_path = [] for sp in sps: try: sp = Importer.module_path(sp) except: pass try: static_path.append(sp) static_builder = StaticBuilder(sp, not_compile) if build: static_builder.build() if build: self.wsgi_app = SharedDataMiddleware( self.wsgi_app, {url_path: sp + "/build"}, cache=False) else: self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {url_path: sp}, cache=False) except: pass if merge: self.options["views"]["static_path"] = self.options["views"][ "static_path"] + static_path else: self.options["views"]["static_path"] = static_path def init_db(self): if "models" in self.options: metadata.bind = self.options["models"]["connection"] metadata.bind.echo = False def init_session(self): session_options = { 'session.type': self.options["views"]['session_type'], "session.auto": self.options["views"]["session_auto"], 'session.cookie_expires': self.options["views"]['session_cookie_expires'], 'session.encrypt_key': self.options["views"]['session_encrypt_key'], 'session.validate_key': self.options["views"]['session_validate_key'] } self.wsgi_app = SessionMiddleware(self.wsgi_app, session_options, environ_key="session") def init_server(self): #kwargs = dict(filter(lambda item: item[0] not in ["address", "port"], self.options["application"].iteritems())) kwargs = {} if "system" in self.options["application"]: kwargs = self.options["application"]["system"] self.server = WSGIServer((self.options["application"]["address"], self.options["application"]["port"]), self.wsgi_app, **kwargs) def wsgi_app(self, options, start_response): request = Request(options) response = self.router.route(request) return response(options, start_response) def start(self): gevent.signal(signal.SIGTERM, self.stop) gevent.signal(signal.SIGINT, self.stop) self.eventer.publish("ApplicationStarted", self) self.server.serve_forever() def start_no_wait(self): self.eventer.publish("ApplicationStarted", self) self.server.start() def stop(self): self.eventer.publish("ApplicationStopped", self) self.server.stop()
class Router(Singleton): """ Router implements unique hierarchical url mapping. Pass dictionary with mapping of regex and controller. """ def __init__(self, options): self.options = options self.logger = logging.getLogger(__name__) self.eventer = Eventer() self.add_urls(self.options["urls"], False) if "templates_path" in self.options["views"]: tps = [] for tp in self.options["views"]["templates_path"]: tps.append(PackageLoader(tp, "")) self.options["views"]["templates_environment"] = Environment( loader=ChoiceLoader(tps), extensions=self.options["views"]["templates_extensions"]) def add_urls(self, urls, merge=True): urls = Dict.flat_dict(urls) new_urls = [] for k, v in urls.iteritems(): if k[len(k) - 2] == "/": k = k[:len(k) - 2] + k[len(k) - 1] k = re.compile(k) if inspect.isclass(v): new_urls.append((k, v())) else: new_urls.append((k, v)) if merge: self.options["urls"] = self.options["urls"] + new_urls else: self.options["urls"] = new_urls def route(self, request): for (re_url, controller) in self.options["urls"]: path = request.path.lower() if path[len(path) - 1] == "/": path = path.rstrip('/') mtch = re_url.match(path) if mtch: request.params = mtch.groupdict() try: self.eventer.publish("BeforeControllerAction", request) #check if controller has method for all requests if hasattr(controller, "process") and inspect.ismethod( getattr(controller, "process")): action = getattr(controller, "process") else: action = getattr(controller, request.method.lower()) response = action(request) self.eventer.publish("AfterControllerAction", request, response) if not response: break log_code = 0 if hasattr(response, "status_code"): log_code = response.status_code else: log_code = response.code self.logger.info(Router.format_log(request, log_code)) return response except HTTPException, e: response = self.get_err_page(e) log_code = 0 if hasattr(response, "status_code"): log_code = response.status_code else: log_code = response.code self.logger.warning(Router.format_log( request, log_code, str(e)), exc_info=True) return response except Exception, e: response = self.get_err_page( InternalServerError( description=traceback.format_exc())) log_code = 0 if hasattr(response, "status_code"): log_code = response.status_code else: log_code = response.code self.logger.error(Router.format_log( request, log_code, str(e)), exc_info=True) return response
class Application(Singleton): """ Main class of your application. Pass options to constructor and all subsystems(eventer, router, db_engine) will be configured. """ def __init__(self, options): self.init_options(options) self.init_eventer() self.init_router() self.init_templater() self.eventer.publish("BeforeDatabaseEngineConfiguration", self) self.init_db() self.eventer.publish("AfterDatabaseEngineConfiguration", self) self.init_session() self.eventer.publish("BeforeInitStatic", self) self.init_static() self.eventer.publish("AfterInitStatic", self) self.eventer.publish("BeforeInitServer", self) self.init_server() self.eventer.publish("AfterInitServer", self) self.eventer.publish("BeforeApplicationStarted", self) def init_options(self, options): logging.basicConfig(level=logging.CRITICAL) default_options = { "application": { "address": "127.0.0.1", "port": 8080 }, "urls": {}, "views": { "templates_path": [], "templates_extensions": ["compressinja.html.HtmlCompressor", "jinja2.ext.i18n"], "static_path": [], 'session_type': "cookie", "session_auto": True, 'session_cookie_expires': True, 'session_encrypt_key':'sldk24j0jf09w0jfg24', 'session_validate_key':';l[pfghopkqeq1234,fs' }, "events": {} } self.options = Dict.merge(default_options, options) def init_eventer(self): self.eventer = Eventer(self.options["events"]) def init_router(self): self.router = Router(self.options) def init_templater(self): self.templater = Templater(self) def init_static(self): static_builder = None self.add_static(self.options["views"]["static_path"], merge=False) def add_static(self, sps, url_path="/", merge=True): static_path = [] for sp in sps: try: sp = Importer.module_path(sp) except: pass try: static_path.append(sp) static_builder = StaticBuilder(sp) static_builder.build() self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {url_path : sp + "/build"}, cache=False) except: pass if merge: self.options["views"]["static_path"] = self.options["views"]["static_path"] + static_path else: self.options["views"]["static_path"] = static_path def init_db(self): if "models" in self.options: metadata.bind = self.options["models"]["connection"] metadata.bind.echo = False def init_session(self): session_options = { 'session.type': self.options["views"]['session_type'], "session.auto": self.options["views"]["session_auto"], 'session.cookie_expires': self.options["views"]['session_cookie_expires'], 'session.encrypt_key': self.options["views"]['session_encrypt_key'], 'session.validate_key': self.options["views"]['session_validate_key'] } self.wsgi_app = SessionMiddleware(self.wsgi_app, session_options, environ_key="session") def init_static_server(self): for sp in self.options["views"]["static_path"]: self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {'/': sp + "/build"}) def init_server(self): kwargs = dict(filter(lambda item: item[0] not in ["address", "port"], self.options["application"].iteritems())) self.server = WSGIServer((self.options["application"]["address"], self.options["application"]["port"]), self.wsgi_app, **kwargs) def wsgi_app(self, options, start_response): request = Request(options) response = self.router.route(request) return response(options, start_response) def start(self): gevent.signal(signal.SIGTERM, self.stop) gevent.signal(signal.SIGINT, self.stop) self.eventer.publish("ApplicationStarted", self) self.server.serve_forever() def start_no_wait(self): self.eventer.publish("ApplicationStarted", self) self.server.start() def stop(self): self.eventer.publish("ApplicationStopped", self) self.server.stop() if self.db_engine: self.db_engine.close()