Briefly introduce some key points of self-writing the web framework in Python

Source: Internet
Author: User
Tags define get set cookie
This article briefly introduces some important points of self-writing the web framework in Python. the sample code is based on Python 2.x. if you need it, refer to the following before you officially start Web development, we need to compile a Web framework.

Why did I choose not a ready-made Web framework but develop it from scratch? Let's take a look at the existing popular Web framework:

  • Django: one-stop development framework, but not customized;
  • Web. py: use a class instead of a simpler function to process URLs, and URL ING is configured separately;
  • Flask: The URL routing using @ decorator is good, but the framework intrusion into the application code is too strong;
  • Bottle: The function of blocking based on URL mode is missing, which is not conducive to permission check.

Therefore, we design a simple, flexible, and lightweight Web framework based on the advantages of several frameworks.
Design Web framework

A simple URL framework should allow the @ decorator method to directly map the URL to the function:

# Homepage: @ get ('/') def index (): return 'index page' # URL with parameters: @ get ('/user/: ID ') def show_user (id): user = User. get (id) return 'Hello, % s' % user. name

Does @ decorator not change function behavior? that is to say, the API accessibility of the Web framework is very small. you can directly test the function show_user (id) without starting the Web server.

The function can return str, unicode, and iterator. The data can be directly returned to the browser as a string.

Secondly, the Web framework should support the URL interceptor. in this way, we can perform a permission check based on the URL:

@interceptor('/manage/')def check_manage_url(next):  if current_user.isAdmin():    return next()  else:    raise seeother('/signin')

The interceptor accepts a next function, so that an interceptor can decide whether to call next () to continue to process the request or directly return the result.

To support MVC, the Web framework needs to support templates, but we do not limit which template to use. you can select jinja2 or mako or Cheetah.

To unify the template interface, the function can return dict and use @ view to render the template:

@view('index.html')@get('/')def index():  return dict(blogs=get_recent_blogs(), user=get_current_user())

If you need to obtain user input data from the form or querystring of the URL, you need to access the request object. if you want to set a specific Content-Type and set Cookie, you need to access the response object. The request and response objects should be obtained from a unique ThreadLocal:

@get('/test')def test():  input_data = ctx.request.input()  ctx.response.content_type = 'text/plain'  ctx.response.set_cookie('name', 'value', expires=3600)  return 'result'

Finally, if you need to redirect or return an HTTP error code, the best way is to directly throw an exception, for example, redirect to the login page:

raise seeother('/signin')

Error 404 returned:

raise notfound()

Based on the above interface, we can implement the Web framework.
Web Framework Implementation

The basic objects are as follows:

# Transwarp/web. py # global ThreadLocal object: ctx = threading. local () # HTTP error class: class HttpError (Exception): pass # request object: class Request (object): # Return value: def get (self, key, default = None): pass # Return key-value dict: def input (self): pass # return URL path: @ property def path_info (self ): pass # HTTP Headers returned: @ property def headers (self): pass # Cookie returned based on key value: def cookie (self, name, default = None): pass # response object: class Response (object): # set header: def set_header (self, key, value): pass # Set Cookie: def set_cookie (self, name, value, max_age = None, expires = None, path = '/'): pass # set status: @ property def status (self): pass @ status. setter def status (self, value): pass # define GET: def get (path): pass # define POST: def post (path): pass # define template: def view (path): pass # define interceptor: def interceptor (pattern): pass # define template engine: class TemplateEngine (object): def _ call _ (self, path, model): pass # jinja2: class Jinja2TemplateEngine (TemplateEngine): def _ init _ (self, templ_dir, ** kw): from jinja2 import Environment, FileSystemLoader self. _ env = Environment (loader = FileSystemLoader (templ_dir), ** kw) def _ call _ (self, path, model): return self. _ env. get_template (path ). render (** model ). encode ('utf-8 ')

After filling out the above definition, we have only one thing left: define the global WSGIApplication class, implement the WSGI interface, and then complete the work of the entire Web framework through configuration startup.

To design WSGIApplication, you must fully consider the distinction between the Development Mode and the Production Mode. In product mode, WSGIApplication needs to directly provide the WSGI interface to the server for the server to call this interface. in development mode, we prefer to use the app. run () directly start the server for development and debugging:

Wsgi = WSGIApplication () if _ name _ = '_ main _': wsgi. run () else: application = wsgi. get_wsgi_application (). Therefore, WSGIApplication is defined as follows: class WSGIApplication (object): def _ init _ (self, document_root = None, ** kw): pass # Add a URL definition: def add_url (self, func): pass # Add an Interceptor definition: def add_interceptor (self, func): pass # set TemplateEngine: @ property def template_engine (self ): pass @ template_engine.setter def template_engine (self, engine): pass # return WSGI processing function: def get_wsgi_application (self): def wsgi (env, start_response ): pass return wsgi # Start the server directly in development mode: def run (self, port = 9000, host = '123. 0.0.1 '): from wsgiref. simple_server import make_server server = make_server (host, port, self. get_wsgi_application () server. serve_forever () Try

After filling the WSGIApplication class, we have a complete Web framework.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.