如何让 eve 以编程方式创建 DOMAIN 端点

How to make eve create DOMAIN endpoints programmatically

我正在尝试让 Python Eve 以编程方式创建不同的集合,

假设我想公开一个接收模式的端点,以便能够在 mongo 中创建该集合:

DOMAIN = {}

app.route('/gen')
def gen(schema):
    app.config['DOMAIN'][schema.name] = schema.def # <-- This obviously does not work, don't know how to focus it

这样通过 curl 我可以 post 这个模式 def:

curl -H "Content-Type: application/json" -d '[{"name":"test", "def": "{\"age\":\"int\"}"}]' http://localhost:5000/gen

并且创建了这个新集合(测试)的 POST 个对象

curl -H "Content-Type: application/json" -d '[{"age":5]' http://localhost:5000/test

显然这只是最初的问题。为了在未来保留它,我需要将这些数据保存在 mongo 中,并在应用程序启动时加载它,以便 "mongo autodefines python eve DOMAIN itself"。希望这也能实现

我的方法是对 Eve() 对象使用自定义设置:

app = eve.Eve(settings=settings)

其中 settings 包含 DOMAIN 定义:

settings = {
    "SERVER_NAME": None,
    "DEBUG": True,

    # MongoDB params
    "MONGO_HOST": '...',
    "MONGO_PORT": 27017,
    "MONGO_USERNAME": '...',
    "MONGO_PASSWORD": '...',

    .....

    # add to DOMAIN all collections defined in `schema`
    "DOMAIN": {
        # doc
        'app_doc': {
            'item_title': 'app_doc',
            'resource_methods': ['GET', 'POST', 'DELETE'],
            'allow_unknown': True,
            'schema': {
                'name': {'type': 'string', 'required': True},
    ....
}

可以修改设置变量以便从数据库接收参数(我使用一个名为 app_schema 的集合,我在其中保留这些端点的自定义定义)。

只需在 Eve() 实例化之前连接到 Mongo(我使用 pymongo),然后用 app_schema 集合中的所有数据填充 settings["DOMAIN"],然后传递此设置变量至 Eve(settings=settings)。此处示例:

# setup Mongo connection (@see config.py - store here default schemas and DOMAIN)
client = MongoClient(settings["MONGO_HOST"], settings["MONGO_PORT"])
db = client.docfill

# check app_schema collection
tab_schemas = db.app_schema.find({})


def load_settings_from_schema_collection():
    """
    Defines a new settings DOMAIN variable loaded with metadata regarding "ent_"-collections
        create other API endpoints by definitions found in schema
        this is a huge workload, as it analyzes each schemadef and create endpoints for various operations
        like GET/POST/DEL/PUT/PATCH and search
        :return:
    """
    i = 0

    # add to `settings` new definitions from app_schema collection
    global settings

    # now parse each doc and create settings table for it, the insert settings table into DOMAIN definition
    for doc in tab_schemas:
        i = i + 1
        # this name should be unique for each collection
        this_collection_name = "ent_" + doc["collection"]
        # only allow "ent_" prefixed schemas to be overridden
        this_schema_setting = {
            "datasource": {
                "source": this_collection_name  # important ca tabela sa fie definita cu prefix
            },
            "resource_methods": ['GET', 'POST', 'DELETE'],
            "item_methods": ['GET', 'DELETE', 'PUT', 'PATCH'],
            "schema": {}
        }

        for fld_meta in doc["content"]:
            this_schema_setting["schema"][fld_meta] = {"type": doc["content"][fld_meta]["type"]}

            # is there a required option ?
            if "required" in doc["content"][fld_meta]:
                this_schema_setting["schema"][fld_meta] = {"required": bool(doc["content"][fld_meta]["required"])}

        settings["DOMAIN"][this_collection_name] = this_schema_setting

        # output everything in settings variable to config.js (just for viewing what happens in settings)
        file = "config.js"
        with open(file, 'w') as filetowrite:
            filetowrite.write('settings = ' + json.dumps(settings, indent=4, sort_keys=True))

    return 1


# load settings from schema collections in MongoDB: collection=app_schema
load_settings_from_schema_collection()

最后,启动服务器:

app = eve.Eve(settings=settings)

app.run(...)

希望对您有所帮助!