成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通過demo學(xué)習(xí)OpenStack開發(fā)所需的基礎(chǔ)知識 -- API服務(wù)(3)

ybak / 1408人閱讀

摘要:從上面的例子可以看出,決定響應(yīng)類型的主要是傳遞給函數(shù)的參數(shù),我們看下函數(shù)的完整聲明參數(shù)用來指定返回值的模板,如果是就會返回內(nèi)容,這里可以指定一個文件,或者指定一個模板。用來做什么上面兩節(jié)已經(jīng)說明了可以比較好的處理請求中的參數(shù)以及控制返回值。

上一篇文章我們了解了一個巨啰嗦的框架:Paste + PasteDeploy + Routes + WebOb。后來OpenStack社區(qū)的人受不了這么啰嗦的代碼了,決定換一個框架,他們最終選中了Pecan。Pecan框架相比上一篇文章的啰嗦框架有如下好處:

不用自己寫WSGI application了

請求路由很容易就可以實現(xiàn)了

總的來說,用上Pecan框架以后,很多重復(fù)的代碼不用寫了,開發(fā)人員可以專注于業(yè)務(wù),也就是實現(xiàn)每個API的功能。

Pecan

Pecan框架的目標(biāo)是實現(xiàn)一個采用對象分發(fā)方式進行URL路由的輕量級Web框架。它非常專注于自己的目標(biāo),它的大部分功能都和URL路由以及請求和響應(yīng)的處理相關(guān),而不去實現(xiàn)模板、安全以及數(shù)據(jù)庫層,這些東西都可以通過其他的庫來實現(xiàn)。關(guān)于Pecan的更多信息,可以查看文檔:https://pecan.readthedocs.org/en/latest/index.html。本文以O(shè)penStack的magnum項目為例來說明Pecan項目在實際中的應(yīng)用,但是本文不會詳細(xì)講解Pecan的各個方面,一些細(xì)節(jié)請讀者閱讀Pecan的文檔。

項目中的代碼結(jié)構(gòu)

使用Pecan框架時,OpenStack項目一般會把API服務(wù)的實現(xiàn)都放在一個api目錄下,比如magnum項目是這樣的:

? ~/openstack/env/p/magnum git:(master) $ tree magnum/api
magnum/api
├── app.py
├── auth.py
├── config.py
├── controllers
│?? ├── base.py
│?? ├── __init__.py
│?? ├── link.py
│?? ├── root.py
│?? └── v1
│??     ├── base.py
│??     ├── baymodel.py
│??     ├── bay.py
│??     ├── certificate.py
│??     ├── collection.py
│??     ├── container.py
│??     ├── __init__.py
│??     ├── magnum_services.py
│??     ├── node.py
│??     ├── pod.py
│??     ├── replicationcontroller.py
│??     ├── service.py
│??     ├── types.py
│??     ├── utils.py
│??     └── x509keypair.py
├── expose.py
├── hooks.py
├── __init__.py
├── middleware
│?? ├── auth_token.py
│?? ├── __init__.py
│?? └── parsable_error.py
├── servicegroup.py
└── validation.py

你也可以在Ceilometer項目中看到類似的結(jié)構(gòu)。介紹一下幾個主要的文件,這樣你以后看到一個使用Pecan的OpenStack項目時就會比較容易找到入口。

app.py 一般包含了Pecan應(yīng)用的入口,包含應(yīng)用初始化代碼

config.py 包含Pecan的應(yīng)用配置,會被app.py使用

controllers/ 這個目錄會包含所有的控制器,也就是API具體邏輯的地方

controllers/root.py 這個包含根路徑對應(yīng)的控制器

controllers/v1/ 這個目錄對應(yīng)v1版本的API的控制器。如果有多個版本的API,你一般能看到v2等目錄。

代碼變少了:application的配置

Pecan的配置很容易,通過一個Python源碼式的配置文件就可以完成基本的配置。這個配置的主要目的是指定應(yīng)用程序的root,然后用于生成WSGI application。我們來看Magnum項目的例子。Magnum項目有個API服務(wù)是用Pecan實現(xiàn)的,在magnum/api/config.py文件中可以找到這個文件,主要內(nèi)容如下:

app = {
    "root": "magnum.api.controllers.root.RootController",
    "modules": ["magnum.api"],
    "debug": False,
    "hooks": [
        hooks.ContextHook(),
        hooks.RPCHook(),
        hooks.NoExceptionTracebackHook(),
    ],
    "acl_public_routes": [
        "/"
    ],
}

上面這個app對象就是Pecan的配置,每個Pecan應(yīng)用都需要有這么一個名為app的配置。app配置中最主要的就是root的值,這個值表示了應(yīng)用程序的入口,也就是從哪個地方開始解析HTTP的根path:/hooks對應(yīng)的配置是一些Pecan的hook,作用類似于WSGI Middleware。

有了app配置后,就可以讓Pecan生成一個WSGI application。在Magnum項目中,magnum/api/app.py文件就是生成WSGI application的地方,我們來看一下這個的主要內(nèi)容:

def get_pecan_config():
    # Set up the pecan configuration
    filename = api_config.__file__.replace(".pyc", ".py")
    return pecan.configuration.conf_from_file(filename)


def setup_app(config=None):
    if not config:
        config = get_pecan_config()

    app_conf = dict(config.app)

    app = pecan.make_app(
        app_conf.pop("root"),
        logging=getattr(config, "logging", {}),
        wrap_app=middleware.ParsableErrorMiddleware,
        **app_conf
    )

    return auth.install(app, CONF, config.app.acl_public_routes)

get_pecan_config()方法讀取我們上面提到的config.py文件,然后返回一個pecan.configuration.Config對象。setup_app()函數(shù)首先調(diào)用get_pecan_config()函數(shù)獲取application的配置,然后調(diào)用pecan.make_app()函數(shù)創(chuàng)建了一個WSGI application,最后調(diào)用了 auth.install()函數(shù)(也就是magnum.api.auth.install()函數(shù))為剛剛生成的WSGI application加上Keystone的認(rèn)證中間件(確保所有的請求都會通過Keystone認(rèn)證)。

到這邊為止,一個Pecan的WSGI application就已經(jīng)準(zhǔn)備好了,只要調(diào)用這個setup_app()函數(shù)就能獲得。至于如何部署這個WSGI application,請參考WSGI簡介這篇文章。

從Magnum這個實際的例子可以看出,使用了Pecan之后,我們不再需要自己寫那些冗余的WSGI application代碼了,直接調(diào)用Pecan的make_app()函數(shù)就能完成這些工作。另外,對于之前使用PasteDeploy時用到的很多WSGI中間件,可以選擇使用Pecan的hooks機制來實現(xiàn),也選擇使用WSGI中間件的方式來實現(xiàn)。在Magnum的API服務(wù)就同時使用了這兩種方式。其實,Pecan還可以和PasteDeploy一起使用,Ceilometer項目就是這么做的,大家可以看看。

確定路由變得容易了:對象分發(fā)式的路由

Pecan不僅縮減了生成WSGI application的代碼,而且也讓開發(fā)人員更容易的指定一個application的路由。Pecan采用了一種對象分發(fā)風(fēng)格(object-dispatch style)的路由模式。我們直接通過例子來解釋這種路由模式,還是以Magnum項目為例。

上面提到了,Magnum的API服務(wù)的root是magnum.api.controllers.root.RootController。這里的RootController的是一個類,我們來看它的代碼:

class RootController(rest.RestController):

    _versions = ["v1"]
    """All supported API versions"""

    _default_version = "v1"
    """The default API version"""

    v1 = v1.Controller()

    @expose.expose(Root)
    def get(self):
        # NOTE: The reason why convert() it"s being called for every
        #       request is because we need to get the host url from
        #       the request object to make the links.
        return Root.convert()

    @pecan.expose()
    def _route(self, args):
        """Overrides the default routing behavior.

        It redirects the request to the default version of the magnum API
        if the version number is not specified in the url.
        """

        if args[0] and args[0] not in self._versions:
            args = [self._default_version] + args
        return super(RootController, self)._route(args)

別看這個類這么長,我來解釋一下你就懂了。首先,你可以先忽略掉_route()函數(shù),這個函數(shù)是用來覆蓋Pecan的默認(rèn)路由實現(xiàn)的,在這里去掉它不妨礙我們理解Pecan(這里的_route()函數(shù)的作用把所有請求重定向到默認(rèn)的API版本去)。去掉_route()和其他的東西后,整個類就變成這么短:

class RootController(rest.RestController):
    v1 = v1.Controller()

    @expose.expose(Root)
    def get(self):
        return Root.convert()

首先,你要記住,這個RootController對應(yīng)的是URL中根路徑,也就是path中最左邊的/。

RootController繼承自rest.RestController,是Pecan實現(xiàn)的RESTful控制器。這里的get()函數(shù)表示,當(dāng)訪問的是GET /時,由該函數(shù)處理。get()函數(shù)會返回一個WSME對象,表示一個形式化的HTTP Response,這個下面再講。get()函數(shù)上面的expose裝飾器是Pecan實現(xiàn)路由控制的一個方式,被expose的函數(shù)才會被路由處理。

這里的v1 = v1.Controller()表示,當(dāng)訪問的是GET /v1或者GET /v1/...時,請求由一個v1.Controller實例來處理。

為了加深大家的理解,我們再來看下v1.Controller的實現(xiàn):

class Controller(rest.RestController):
    """Version 1 API controller root."""

    bays = bay.BaysController()
    baymodels = baymodel.BayModelsController()
    containers = container.ContainersController()
    nodes = node.NodesController()
    pods = pod.PodsController()
    rcs = rc.ReplicationControllersController()
    services = service.ServicesController()
    x509keypairs = x509keypair.X509KeyPairController()
    certificates = certificate.CertificateController()

    @expose.expose(V1)
    def get(self):
        return V1.convert()

    ...

上面這個Controller也是繼承自rest.RestController。所以它的get函數(shù)表示,當(dāng)訪問的是GET /v1的時候,要做的處理。然后,它還有很多類屬性,這些屬性分別表示不同URL路徑的控制器:

/v1/bays 由bays處理

/v1/baymodels 由baymodels處理

/v1/containers 由containers處理

其他的都是類似的。我們再繼續(xù)看bay.BaysController的代碼:

class BaysController(rest.RestController):
    """REST controller for Bays."""
    def __init__(self):
        super(BaysController, self).__init__()

    _custom_actions = {
        "detail": ["GET"],
    }

    def get_all(...):
    
    def detail(...):
    
    def get_one(...):
    
    def post(...):
    
    def patch(...):

    def delete(...):

這個controller中只有函數(shù),沒有任何類屬性,而且沒有實現(xiàn)任何特殊方法,所以/v1/bays開頭的URL處理都在這個controller中終結(jié)。這個類會處理如下請求:

GET /v1/bays

GET /v1/bays/{UUID}

POST /v1/bays

PATCH /v1/bays/{UUID}

DELETE /v1/bays/{UUID}

GET /v1/bays/detail/{UUID}

看了上面的3個controller之后,你應(yīng)該能大概明白Pecan是如何對URL進行路由的。這種路由方式就是對象分發(fā):根據(jù)類屬性,包括數(shù)據(jù)屬性和方法屬性來決定如何路由一個HTTP請求。Pecan的文檔中對請求的路由有專門的描述,要想掌握Pecan的路由還是要完整的看一下官方文檔。

內(nèi)置RESTful支持

我們上面舉例的controller都是繼承自pecan.rest.RestController,這種controller稱為RESTful controller,專門用于實現(xiàn)RESTful API的,因此在OpenStack中使用特別多。Pecan還支持普通的controller,稱為Generic controller。Generic controller繼承自object對象,默認(rèn)沒有實現(xiàn)對RESTful請求的方法。簡單的說,RESTful controller幫我們規(guī)定好了get_one(), get_all(), get(), post()等方法對應(yīng)的HTTP請求,而Generic controller則沒有。關(guān)于這兩種controller的區(qū)別,可以看官方文檔Writing RESTful Web Services with Generic Controllers,有很清楚的示例。

對于RestController中沒有預(yù)先定義好的方法,我們可以通過控制器的_custom_actions屬性來指定其能處理的方法。

class RootController(rest.RestController):
    _custom_actions = {
        "test": ["GET"],
    }

    @expose()
    def test(self):
        return "hello"

上面這個控制器是一個根控制器,指定了/test路徑支持GET方法,效果如下:

 $ curl http://localhost:8080/test
hello% 
那么HTTP請求和HTTP響應(yīng)呢?

上面講了這么多,我們都沒有說明在Pecan中如何處理請求和如何返回響應(yīng)。這個將在下一章中說明,同時我們會引入一個新的庫WSME。

WSME Pecan對請求和響應(yīng)的處理

在開始提到WSME之前,我們先來看下Pecan自己對HTTP請求和響應(yīng)的處理。這樣你能更好的理解為什么會再引入一個WSME庫。

Pecan框架為每個線程維護了多帶帶的請求和響應(yīng)對象,你可以直接在請求處理函數(shù)中訪問。pecan.requestpecan.response分別代表當(dāng)前需要處理的請求和響應(yīng)對象。你可以直接操作這兩個對象,比如指定響應(yīng)的狀態(tài)碼,就像下面這個例子一樣(例子來自官方文檔):

@pecan.expose()
def login(self):
    assert pecan.request.path == "/login"
    username = pecan.request.POST.get("username")
    password = pecan.request.POST.get("password")

    pecan.response.status = 403
    pecan.response.text = "Bad Login!"

這個例子演示了訪問POST請求的參數(shù)以及返回403。你也可以重新構(gòu)造一個pecan.Response對象作為返回值(例子來自官方文檔):

from pecan import expose, Response

class RootController(object):

    @expose()
    def hello(self):
        return Response("Hello, World!", 202)

另外,HTTP請求的參數(shù)也會可以作為控制器方法的參數(shù),還是來看幾個官方文檔的例子:

class RootController(object):
    @expose()
    def index(self, arg):
        return arg

    @expose()
    def kwargs(self, **kwargs):
        return str(kwargs)

這個控制器中的方法直接返回了參數(shù),演示了對GET請求參數(shù)的處理,效果是這樣的:

$ curl http://localhost:8080/?arg=foo
foo
$ curl http://localhost:8080/kwargs?a=1&b=2&c=3
{u"a": u"1", u"c": u"3", u"b": u"2"}

有時候,參數(shù)也可能是URL的一部分,比如最后的一段path作為參數(shù),就像下面這樣:

class RootController(object):
    @expose()
    def args(self, *args):
        return ",".join(args)

效果是這樣的:

$ curl http://localhost:8080/args/one/two/three
one,two,three

另外,我們還要看一下POST方法的參數(shù)如何處理(例子來自官方文檔):

class RootController(object):
    @expose()
    def index(self, arg):
        return arg

效果如下,就是把HTTP body解析成了控制器方法的參數(shù):

$ curl -X POST "http://localhost:8080/" -H "Content-Type: application/x-www-form-urlencoded" -d "arg=foo"
foo
返回JSON還是HTML?

如果你不是明確的返回一個Response對象,那么Pecan中方法的返回內(nèi)容類型就是由expose()裝飾器決定的。默認(rèn)情況下,控制器的方法返回的content-type是HTML。

class RootController(rest.RestController):
    _custom_actions = {
        "test": ["GET"],
    }

    @expose()
    def test(self):
        return "hello"

效果如下:

 $ curl -v http://localhost:8080/test
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.38.0
> Host: localhost:8080
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Tue, 15 Sep 2015 14:31:28 GMT
< Server: WSGIServer/0.1 Python/2.7.9
< Content-Length: 5
< Content-Type: text/html; charset=UTF-8
<
* Closing connection 0
hello% 

也可以讓它返回JSON:

class RootController(rest.RestController):
    _custom_actions = {
        "test": ["GET"],
    }

    @expose("json")
    def test(self):
        return "hello"

效果如下:

 curl -v http://localhost:8080/test
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.38.0
> Host: localhost:8080
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Tue, 15 Sep 2015 14:33:27 GMT
< Server: WSGIServer/0.1 Python/2.7.9
< Content-Length: 18
< Content-Type: application/json; charset=UTF-8
<
* Closing connection 0
{"hello": "world"}% 

甚至,你還可以讓一個控制器方法根據(jù)URL path的來決定是返回HTML還是JSON:

class RootController(rest.RestController):
    _custom_actions = {
        "test": ["GET"],
    }

    @expose()
    @expose("json")
    def test(self):
        return json.dumps({"hello": "world"})

返回JSON:

 $ curl -v http://localhost:8080/test.json
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test.json HTTP/1.1
> User-Agent: curl/7.38.0
> Host: localhost:8080
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Wed, 16 Sep 2015 14:26:27 GMT
< Server: WSGIServer/0.1 Python/2.7.9
< Content-Length: 24
< Content-Type: application/json; charset=UTF-8
<
* Closing connection 0
"{"hello": "world"}"% 

返回HTML:

 $ curl -v http://localhost:8080/test.html
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test.html HTTP/1.1
> User-Agent: curl/7.38.0
> Host: localhost:8080
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Wed, 16 Sep 2015 14:26:24 GMT
< Server: WSGIServer/0.1 Python/2.7.9
< Content-Length: 18
< Content-Type: text/html; charset=UTF-8
<
* Closing connection 0
{"hello": "world"}% 

這里要注意一下:

同一個字符串作為JSON返回和作為HTML返回是不一樣的,仔細(xì)看一下HTTP響應(yīng)的內(nèi)容。

我們的例子中在URL的最后加上了.html后綴或者.json后綴,請嘗試一下不加后綴的化是返回什么?然后,調(diào)換一下兩個expose()的順序再試一下。

從上面的例子可以看出,決定響應(yīng)類型的主要是傳遞給expose()函數(shù)的參數(shù),我們看下expose()函數(shù)的完整聲明:

pecan.decorators.expose(template=None,
                        content_type="text/html",
                        generic=False)

template參數(shù)用來指定返回值的模板,如果是"json"就會返回JSON內(nèi)容,這里可以指定一個HTML文件,或者指定一個mako模板。

content_type指定響應(yīng)的content-type,默認(rèn)值是"text/html"。

generic參數(shù)表明該方法是一個“泛型”方法,可以指定多個不同的函數(shù)對應(yīng)同一個路徑的不同的HTTP方法。

看過參數(shù)的解釋后,你應(yīng)該能大概了解expose()函數(shù)是如何控制HTTP響應(yīng)的內(nèi)容和類型的。

用WSME來做什么?

上面兩節(jié)已經(jīng)說明了Pecan可以比較好的處理HTTP請求中的參數(shù)以及控制HTTP返回值。那么為什么我們還需要WSME呢?因為Pecan在做下面這個事情的時候比較麻煩:請求參數(shù)和響應(yīng)內(nèi)容的類型檢查(英文簡稱就是typing)。當(dāng)然,做是可以做的,不過你需要自己訪問pecan.request和pecan.response,然后檢查指定的值的類型。WSME就是為解決這個問題而生的,而且適用場景就是RESTful API。

WSME簡介

WSME的全稱是Web Service Made Easy,是專門用于實現(xiàn)REST服務(wù)的typing庫,讓你不需要直接操作請求和響應(yīng),而且剛好和Pecan結(jié)合得非常好,所以O(shè)penStack的很多項目都使用了Pecan + WSME的組合來實現(xiàn)API(好吧,我看過的項目,用了Pecan的都用了WSME)。WSME的理念是:在大部分情況下,Web服務(wù)的輸入和輸出對數(shù)據(jù)類型的要求都是嚴(yán)格的。所以它就專門解決了這個事情,然后把其他事情都交給其他框架去實現(xiàn)。因此,一般WSME都是和其他框架配合使用的,支持Pecan、Flask等。WSME的文檔地址是http://wsme.readthedocs.org/en/latest/index.html。

WSME的使用

用了WSME后的好處是什么呢?WSME會自動幫你檢查HTTP請求和響應(yīng)中的數(shù)據(jù)是否符合預(yù)先設(shè)定好的要求。WSME的主要方式是通過裝飾器來控制controller方法的輸入和輸出。WSME中主要使用兩個控制器:

@signature: 這個裝飾器用來描述一個函數(shù)的輸入和輸出。

@wsexpose: 這個裝飾器包含@signature的功能,同時會把函數(shù)的路由信息暴露給Web框架,效果就像Pecan的expose裝飾器。

這里我們結(jié)合Pecan來講解WSME的使用。先來看一個原始類型的例子:

from wsmeext.pecan import wsexpose

class RootController(rest.RestController):
    _custom_actions = {
        "test": ["GET"],
    }

    @wsexpose(int, int)
    def test(self, number):
        return number

如果不提供參數(shù),訪問會失?。?/p>

$ curl http://localhost:8080/test
{"debuginfo": null, "faultcode": "Client", "faultstring": "Missing argument: "number""}% 

如果提供的參數(shù)不是整型,訪問也會失?。?/p>

$ curl http://localhost:8080/test?number=a
{"debuginfo": null, "faultcode": "Client", "faultstring": "Invalid input for field/attribute number. Value: "a". unable to convert to int"}% 

上面這些錯誤信息都是由WSME框架直接返回的,還沒有執(zhí)行到你寫的方法。如果請求正確,那么會是這樣的:

$ curl -v http://localhost:8080/test?number=1
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test?number=1 HTTP/1.1
> User-Agent: curl/7.38.0
> Host: localhost:8080
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Wed, 16 Sep 2015 15:06:35 GMT
< Server: WSGIServer/0.1 Python/2.7.9
< Content-Length: 1
< Content-Type: application/json; charset=UTF-8
<
* Closing connection 0
1% 

請注意返回的content-type,這里返回JSON是因為我們使用的wsexpose設(shè)置的返回類型是XML和JSON,并且JSON是默認(rèn)值。上面這個例子就是WSME最簡單的應(yīng)用了。

那么現(xiàn)在有下面這些問題需要思考一下:

如果想用POST的方式來傳遞參數(shù),要怎么做呢?提示:要閱讀WSME中@signature裝飾器的文檔。

如果我希望使用/test/1這種方式來傳遞參數(shù)要怎么做呢?提示:要閱讀Pecan文檔中關(guān)于路由的部分。

WSME中支持對哪些類型的檢查呢?WSME支持整型、浮點型、字符串、布爾型、日期時間等,甚至還支持用戶自定義類型。提示:要閱讀WSME文檔中關(guān)于類型的部分。

WSME支持?jǐn)?shù)組類型么?支持。

上面的問題其實也是很多人使用WSME的時候經(jīng)常問的問題。我們將在下一篇文章中使用Pecan + WSME來繼續(xù)開發(fā)我們的demo,并且用代碼來回答上面所有的問題。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37614.html

相關(guān)文章

  • 通過demo學(xué)習(xí)OpenStack開發(fā)需的基礎(chǔ)知識 -- API服務(wù)(1)

    摘要:通過,也就是通過各個項目提供的來使用各個服務(wù)的功能。通過使用的方式是由各個服務(wù)自己實現(xiàn)的,比如負(fù)責(zé)計算的項目實現(xiàn)了計算相關(guān)的,負(fù)責(zé)認(rèn)證的項目實現(xiàn)了認(rèn)證和授權(quán)相關(guān)的。的服務(wù)都是使用的方式來部署的。 使用OpenStack服務(wù)的方式 OpenStack項目作為一個IaaS平臺,提供了三種使用方式: 通過Web界面,也就是通過Dashboard(面板)來使用平臺上的功能。 通過命令行,也就...

    Jason_Geng 評論0 收藏0
  • 通過demo學(xué)習(xí)OpenStack開發(fā)需的基礎(chǔ)知識 -- 數(shù)據(jù)庫(2)

    摘要:在實際項目中,這么做肯定是不行的實際項目中不會使用內(nèi)存數(shù)據(jù)庫,這種數(shù)據(jù)庫一般只是在單元測試中使用。接下來,我們將會了解中單元測試的相關(guān)知識。 在上一篇文章,我們介紹了SQLAlchemy的基本概念,也介紹了基本的使用流程。本文我們結(jié)合webdemo這個項目來介紹如何在項目中使用SQLAlchemy。另外,我們還會介紹數(shù)據(jù)庫版本管理的概念和實踐,這也是OpenStack每個項目都需要做的...

    mingzhong 評論0 收藏0
  • 通過demo學(xué)習(xí)OpenStack開發(fā)需的基礎(chǔ)知識 -- API服務(wù)(4)

    摘要:到這里,我們的服務(wù)的框架已經(jīng)搭建完成,并且測試服務(wù)器也跑起來了。上面的代碼也就可以修改為再次運行我們的測試服務(wù)器,就可以返現(xiàn)返回值為格式了。我們先來完成利用來檢查返回值的代碼方法的第一個參數(shù)表示返回值的類型這樣就完成了的返回值檢查了。 上一篇文章說到,我們將以實例的形式來繼續(xù)講述這個API服務(wù)的開發(fā)知識,這里會使用Pecan和WSME兩個庫。 設(shè)計REST API 要開發(fā)REST AP...

    meislzhua 評論0 收藏0
  • 通過demo學(xué)習(xí)OpenStack開發(fā)需的基礎(chǔ)知識 -- 單元測試

    摘要:本文將進入單元測試的部分,這也是基礎(chǔ)知識中最后一個大塊。本文將重點講述和中的單元測試的生態(tài)環(huán)境。另外,在中指定要運行的單元測試用例的完整語法是。中使用模塊管理單元測試用例。每個項目的單元測試代碼結(jié)構(gòu)可 本文將進入單元測試的部分,這也是基礎(chǔ)知識中最后一個大塊。本文將重點講述Python和OpenStack中的單元測試的生態(tài)環(huán)境。 單元測試的重要性 github上有個人畫了一些不同語言的學(xué)...

    douzifly 評論0 收藏0
  • 通過demo學(xué)習(xí)OpenStack開發(fā)需的基礎(chǔ)知識 -- 軟件包管理

    摘要:不幸的是,在軟件包管理十分混亂,至少歷史上十分混亂。的最大改進是將函數(shù)的參數(shù)單獨放到一個的文件中這些成為包的元數(shù)據(jù)?;诘陌姹咎柟芾?。的版本推導(dǎo)這里重點說明一下基于的版本號管理這個功能。開發(fā)版本號的形式如下。 為什么寫這個系列 OpenStack是目前我所知的最大最復(fù)雜的基于Python項目。整個OpenStack項目包含了數(shù)十個主要的子項目,每個子項目所用到的庫也不盡相同。因此,對于...

    blastz 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<