Pyramid(Pythonのwebフレームワーク)メモ

Pyramid始めました。ので、設定メモ。

# URLの設定

## 基本的なrouteの使い方

configの設定

```python
if __name__ == '__main__':
    with Configurator() as config:
        config.add_route('ルートの名前', 'urlの指定')  # ルートの追加
        config.scan()  # 確定
```

呼ばれる関数

```python
@view_config(route_name='ルートの名前', renderer='json')
def 適当な関数名(request):
    処理
    return {}  # rendererにjsonを設定しておくとオブジェクトがそのまま返せる
```

## API的なrouteの使い方

configの設定時に{}でパラメータの受取を設定することができる。よくある /users/user_id/login とかにアクセスした時に、user_idとloginの部分を受け取るようにするには、

```python
if __name__ == '__main__':
    with Configurator() as config:
        config.add_route('ルートの名前', '/users/{id}{func:.*}')
        config.scan()  # 確定
```
としておく。user_idの部分がidに、/loginがfuncに設定される。呼ばれる関数側では、requestオブジェクトのmatchdictを参照すれば値を取得できる。

```python
@view_config(route_name='ルートの名前', renderer='json')
def 適当な関数名(request):
    if(request.matchdict["func"] == "/login"):
        /users/user_id/loginのuser_idの部分で指定されてたユーザーのログイン処理を行う
        user_idはurlの{id}という設定により、request.matchdict["id"]に格納されている

    elif(request.matchdict["func"] == ""):
        url呼び出し時に/users/user_idとした場合funcが空なので、例えばRESTであればGETの処理を行う

    return {}  # rendererにjsonを設定しておくとオブジェクトがそのまま返せる
```
## routeで呼び出す関数(@view_configがついた関数)を別モジュールに置きたい

関数があるモジュール内でconfig.scan()を呼ぶ。

でも面倒くさいんで、たぶんモジュール内の@view_configとっぱらってメインモジュールでこう書いちゃう_(:3」∠)_

```python
# const/const_map.py内のconst_map関数を呼び出す
sys.path.append("const")
from const_map import *

@view_config(route_name='const_map', renderer='json')
def call_const_map(request):
    return const_map(request)
```


## 静的ファイル配信

デバッグ用の静的ファイル配信機能を持っている

```python
if __name__ == '__main__':
    with Configurator() as config:
        config.add_static_view(name='アクセスURL', path='公開するディレクトリ指定。相対パスも可')
```

# pyramid-mongoengineの使い方

## configの設定

pcreateを使ってなくてiniファイル群が無い場合(1ファイルスタート)、マニュアル読んでもiniに設定しろとしか書いてなくてどうすればいいのかと(´・ω・｀)
configにmongo_urlとmongodb_nameを設定すればOK。

```python
if __name__ == '__main__':
    with Configurator() as config:
        config.add_settings({
            "mongo_url": "mongodb://ホストのurl[:ポート(省略可)]",
            "mongodb_name": "使用するDB名",
        })
        config.include("pyramid_mongoengine")
        config.add_connection_database()
```

## 使い方

### コレクションアクセス用クラス

MogoEngineのインスタンスを作っておき、それを使ってクラスを構築する。クラス名はmongodbのコレクション名に対応するので、適当につけてはいけない。UserEventとかクラス名につけると、user_eventというコレクションにアクセスできる。

フィールドの型はバリデーションに使われる。型の一覧はこちら
http://docs.mongoengine.org/guide/defining-documents.html#fields

```python
db = MongoEngine()

class クラス名(db.Document):
    フィールド名 = db.フィールドの型(required=True)
```
#### メソッドの使用

MongoEngineは素のMongoDBと書式に少し違いがあるので注意。例えばMongoDBで

```python
    .update({"$set": {"value": value}})
```

と値をupdateする場合、MongoEngineでは

```python
    .update(set__value=value)
```
と$setをset__と書いたりする。

### クエリ

コレクションのリストを取得するには

```python
コレクション用クラス.objects(フィルタ)
```

とすると、コレクション用クラスのインスタンスのリスト(カーソル)が返る。rendererにjsonが指定してあると、このカーソルをそのままreturnできる。

ひとつだけ取り出すには、

```python
.first()
```

を使用する。コレクション用クラスのインスタンスが取得できるので、returnでクライアントに送信したり、加工して.save()したり、コレクション用クラスに書いたメソッドを実行したりできる。結果リストが空の場合はNoneが返る。

#### JSON文字列化

クエリ結果は

```python
.to_json()
```
で、JSON文字列を取得できる。print()でデバッグするときとかに便利。

#### 受け取ったデータから_idを除外

クエリ結果に

```python
.exclude("id")
````
を付ける。

## セッション

### cookie

```python
# import
from pyramid.session import SignedCookieSessionFactory

# config設定
session_factory = SignedCookieSessionFactory('シークレット文字列')
config.set_session_factory(session_factory)
```
設定してあるとレスポンスヘッダに

```
Set-Cookie: session=文字列;
```
が設定される。でも普通cookieセッションとか使わんよね？_(:3」∠)_

### pyramid-beaker

セッションIDだけCookieでやり取りして、実体はサーバが持ってるっていうのをやるのに便利なライブラリ。設定してあるとレスポンスヘッダに

```
Set-Cookie:  beaker.session.id=文字列;
```
が設定される。

#### memoryセッション

個人的にはmemoryセッションが後腐れなくて好きです。まぁ、実運用だとメモリがもったいないので開発時専用ですが。

```python
config.add_settings({
    "session.type": "memory",
    "session.cookie_expires": True,
})
config.include('pyramid_beaker')
```

#### mongodbセッション

セッション情報をmongodbに保存する。指定したDBの中にbacker_cacheというコレクションが作られてそこにデータが保存される。実運用用。

高速にさばきたいならext:memcachedとかでどうぞ。

```python
config.add_settings({
    'session.type': 'ext:mongodb',
    'session.url': 'mongodb://ホスト名:ポート名/DB名',
})
config.include('pyramid_beaker')
```

### 入出力

ルータで呼ばれる関数のrequestオブジェクトのsessionで読み書き

```python
request.session["名前"] = 値
```