33 Matching Annotations
  1. Jun 2023
    1. It is a WSGI toolkit

      این دیگه کار از یه پیاده سازی و Container گذرنده و یک Toolkit کامل است

    1. mod_

      این برای Apache سات

    2. ow

      میگه این Python Application باید یک Callable Object داشته باشه که حاوی یک سری Functionality برای این باشد که توسط Apache صدا زده شود. که انگار این Functionality توسط PEP 3333 درست شده است. حالا این WSGI که خودش یک استاندارد یا Interface است و خیلی اومدن این را پیاده سازی کردن مثل uWSGI یا mod-wsgi. به اینا اصطلاحا میگن WSGI Container.

    3. It expla

      این wsgi برای این است که چگونه یک وب سرور (مثل Apache) درخواست را بفرسته Web Application. و همچنین Web Application چگونه درخواست ها را به صورت زنجیر در بیاره.

  2. Jun 2018
    1. RoutesMiddleware将HTTP的URL请求应声到相应WSGI函数,并且将路由匹配结果存到environ环境变量中去

      RoutesMiddleware 主要作用:

      1. 将HTTP的URL请求映射到相应WSGI函数
      2. 讲路由匹配结果存到environ环境变量中
  3. May 2018
    1. Fanout: 相当于广播,producer 可把消息发送给多个 consumer,属于异步调用范畴,如下图

    2. Cast: 异步调用,producer 发送消息后继续执行后续步骤,consumer 接收处理消息,如下图。

    3. Call: 同步调用,但过程稍微复杂,producer 发送消息后立刻创建一个 direct consumer, 该 direct consumer 阻塞于接收返回值。对端的 consumer 接收并处理 producer 的消息后,创建一个 direct producer,它负责把处理结果发送给 direct consumer

    4. AMQP 是应用层协议,它在 client 和 server 端引入了消息中间件,解耦了 client 和 server 端,支持大规模下的消息通信

      AMQP 引入了消息中间件

      从RPC角度来看,Client端要远程调用Server端的函数

      从AMQP角度来看,Client要发起请求,产生请求消息,所以是Producer,Server端需要获取消息消费,才能进行相应的处理,所以是Consumer

    1. 你可以使用传入type=的方式来使用Opt类,或者直接使用其对应类型的子类例如StrOpt类,如果配置项值无法解析成对应类型,将会抛出一个ValueError错误
      common_opts = [
          cfg.Opt( 'bind_port',
                    type=PortType,
                    default=9292,
                    help='Port number to listen')
      ]
      ### 等价于
      common_opts = [
          cfg.PortOpt( 'bind_port',
                        default=9292,
                        help='Port number to listen')
      ]
      

    Tags

    Annotators

    1. 最后一种使用插件的方式,相当于Drivers加载和Extensions加载的结合。它允许在给定的entry points组名下有同名的entry point,这样,在给定entry points组名和entry point名的情况下,hook式加载会加载所有找到的插件。

      Hook式加载

    2. ExtensionManager和DriverManager略有不同,它不需要提前知道要加载哪个插件,它会加载所有找到的插件。          要想调用插件,需要使用map方法,需要传给map一个函数,这里就是format_data函数,针对每个扩展都会调用该函数。format_data函数有两个参数,分别是Extension实例和map的第二个参数da

      不需要知道插件的具体名字,指定namespace='xxxx',则会加载xxxx entry point group下的所有插件(扩展)

      要调用插件 ==> manager.map(func, args) ==> namespace中的每个插件都会调用该函数func ==> manager.map(func, args) return 一个序列,序列中的每个元素就是每个插件调用回调函数的返回值

    3. 定义并注册插件

      注册插件是通过 setup.py 来注册插件的

      from setuptools import setup, find_packages
      setup(
          name='test',
          version='1.0',
          packages=find_packages(),
          entry_points={
              'namespace': [
                  'name = module:importable'
              ],
          },
      )
      
    4. 在stevedore中,有三种使用插件的方式:Drivers、Hooks、Extensions
      1. Drivers:一个名字对应一个entry point

      2. Hooks:一个名字对应多个entry point

      3. Extensions:多个名字对应多个entry point

    1. 根据每个插件在entry point中名字和具体实现的数量之间的对应关系不同,stevedore提供了多种不同的类来帮助开发者发现和载入插件,如下图所示:

    2. 示例中显示了两个不同的entry points的命名空间,“ceilometer.compute.virt"和"ceilometer.hardware.inspectors",分别注册有3个和1个插件.每个插件都符合"名字=模块:可导入对象”的格式,在“ceilometer.compute.virt"命名空间里的libvirt插件,它的具体可载入的实现是ceilometer.compute.virt.libvirt.inspector模块中的LibvirtInspector类.
      ceilometer.compute.virt =   
          libvirt = ceilometer.compute.virt.libvirt.inspector:LibvirtInspector  
          hyperv = ceilometer.compute.virt.hyperv.inspector:HyperVInspector  
          vsphere = ceilometer.compute.virt.vmware.inspector:VsphereInspector  
      
      ceilometer.hardware.inspectors =  
          snmp = ceilometer.hardware.inspectors.snmp:SNMPInspector
      
      • ceilometer.compute.virt 和 ceilometer.hardware.inspectors是两个命名空间
      • ceilometer.compute.virt 有 libvirt,hyperv,vsphere 三个插件,ceilometer.hardware.inspectors 有 snmp 一个插件
      • 插件的具体可载入实现是每个插件等号后面的具体类
    1. Note Due to how Routes matches a list of URL’s, it has no inherent knowledge of a route being a resource. As such, if a route fails to match due to the method requirements not being met, a 404 will return just like any other failure to match a route.

      注意:由于路由与URL的列表相匹配,它不具有作为资源的路由的固有知识,因此,如果由于未满足方法要求而导致路由不匹配,则404将像任何其他路由失败一样返回以匹配路由。

    1. A static route is used only for generation – not matching – and it must be named. To define a static route, use the argument _static=True.

      静态路由仅用于URL生成,不会用于匹配,并且必须命名。使用参数 _static=True 来定义静态路由

    2. However, if the route defines an extra variable with the same name as a path variable, the extra variable is used as the default if that keyword is not specified.

      但是,如果路由定义了一个额外变量和 url() 的路径变量名称相同,如果未指定该关键字,那么额外变量将用 作默认值

      ### id 作为额外参数
      m.connect("archives", "/archives/{id}",
          controller="archives", action="view", id=1)
      ### id作为路径参数
      url("archives", id=123)  =>  "/archives/123"
      url("archives")  =>  "/archives/1"
      
    3. url("blog", year=2008, month=10, day=2)

      如果路由包含path variables(路径变量),则必须使用关键字参数设置这些变量值:

    4. url("home") => "/"

      要生成一个带名字的路由,指定路由名作为位置参数

    1. If the “path_info” variable is used at the end of the URL, Routes moves everything preceding it into the “SCRIPT_NAME” environment variable. This is useful when delegating to another WSGI application that does its own routing: the subapplication will route on the remainder of the URL rather than the entire URL. You still need the ”:.*” requirement to capture the following URL components into the variable.

      如果在URL的末尾使用“path_info”变量,则Routes会将其前面的所有内容移动到“SCRIPT_NAME”环境变量中。

      当委派另一个WSGI应用程序执行自己的路由时,这非常有用:子应用程序将路由剩余的URL而不是整个URL。

      您仍需要“:.*” requirement 才能将以下URL组件捕获到变量中。

      map.connect(None, "/cards/{path_info:.*}",
          controller="main", action="cards")
      # Incoming URL "/cards/diamonds/4.png"
      => {"controller": "main", action: "cards", "path_info": "/diamonds/4.png"}
      # Second WSGI application sees:
      # SCRIPT_NAME="/cards"   
      # PATH_INFO="/diamonds/4.png"
      
    2. map.connect(None, "/error/{action}/{id}", controller="error")

      Mapper在Web应用程序中处理URL生成和URL识别。

      Mapper是建立处理字典的。 假定Web应用程序将处理返回由URL识别并正确分派的字典。

      通过将关键字参数传递到生成函数来完成URL生成,然后返回一个URL。

      class Mapper(SubMapperParent):
      
          def __init__(self, 
                  controller_scan=controller_scan, 
                  directory=None,
                  always_scan=False, 
                  register=True, 
                  explicit=True):
      ### Create and connect a new 
      ### Route to the Mapper
          def connect(self, 
                      routename, 
                      path=None, 
                      **kwargs):
              ........
      
    1. app_iter = myfunc(environ, start_response) resp = myfunc(req)

      With that myfunc will be a WSGI application, callable like

      app_iter = myfunc(environ, start_response).
      

      You can also call it like normal

      resp = myfunc(req)
      

      You can also wrap methods

      def myfunc(self, req).)
      
    2. @wsgify def myfunc(req): return webob.Response('hey there')

      不添加装饰器,打印type(myfunc)

      <type 'function'>
      

      添加装饰器之后,打印type(myfunc)

      <class 'webob.dec.wsgify'>
      
    3. >>> from webob import Request >>> environ = {'wsgi.url_scheme': 'http', ...} >>> req = Request(environ)
      ### environ 是 WSGI环境变量
      req = Request(environ)
      把 environ 字典 转换成 <class 'webob.request.Request'> Request对象
      所以 webob.Request是对WSGI环境变量的一个封装
      

    Tags

    Annotators

    URL

    1. @classmethod def factory(cls, global_conf, **kwargs): return cls()
      class AnimalApplication(object):
          @classmethod
          def factory(cls, global_conf, **kwargs):
              print cls
              return cls()
      
      <class '__main__.AnimalApplication'>
      ==> cls 指的是类本身
      
    2. eventlet: python 的高并发网络库 paste.deploy: 用于发现和配置 WSGI application 和 server 的库 routes: 处理 http url mapping 的库

      WSGI框架下一些常用的 python module

      • eventlet
      • paste.deploy
      • routes
    1. Middleware 处于 server/gateway 和 application/framework 之间,对 server/gateway 来说,它相当于 application/framework;对 application/framework 来说,它相当于 server/gateway。每个 middleware 实现不同的功能,我们通常根据需求选择相应的 middleware 并组合起来,实现所需的功能

      比如,可在 middleware 中实现以下功能:

      • 根据 url 把用户请求调度到不同的 application 中。
      • 负载均衡,转发用户请求
      • 预处理 XSL 等相关数据
      • 限制请求速率,设置白名单
      middleware 介于 sever/gateway 和 application/framework 之间 该怎么理解
      • 简单考虑,没有middleware时,创建server时指定application,请求发生时,调用application
      • 那么有middleware是什么情况呢?middleware接收application作为入参,这样就把middleware和application这一端连接起来,对于application来说,middleware就像server一样,middleware把application执行结果返回给server,对于server来说,middleware就像application一样
    2. Callable object 必须满足以下两个条件:
      • 接受两个参数:字典dict (environ),回调函数(start_response,返回 HTTP status, headers 给 web server)
      • 返回一个可以迭代的值
    3. PEP 0333 – Python Web Server Gateway Interface 是一种 web server or gateway 和 python web application or framework 之间简单通用的接口,符合这种接口的 application 可运行在所有符合该接口的 server 上

      WSGI -- web server gateway interface

      是一种 web server/gateway 和 python web application/framework 之间的通用接口

      符合这种接口的application,都可以运行在符合该接口的server上

      application <==> web server gateway interface <==> server

    4. a proposed standard interface between web servers and Python web applications or frameworks

      WSGI -- a interface of python web applications or frameworks