校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > python中bottle使用實例代碼

python中bottle使用實例代碼

熱門標簽:ai電銷機器人源碼 地圖標注審核表 外呼并發線路 西藏房產智能外呼系統要多少錢 長沙高頻外呼系統原理是什么 百度地圖標注沒有了 ai電話機器人哪里好 宿遷星美防封電銷卡 湛江智能外呼系統廠家

模仿學習同事的代碼來寫的,主要是搞懂python中如何來組織包,如何調用包,如何讀取配置文件,連接數據庫,設置路由,路由分組。(注:使用的是python3.6)

整體目錄設計如下:

根據調用層級從上往下來說:

首先項目根目錄下的main.py是整個程序的入口,主要作用啟動http服務器,調用分組路由。

main.py

import bottle
from confg.conf import CONF
from api.user import User
 
db_url = CONF.db.url
 
default_app = bottle.default_app()
 
#相當于分組路由
default_app.mount("/user", User(db_url, "").app)
 
app = default_app
 
if __name__ == '__main__':
    bottle.run(app=app,
               host="localhost",
               port="8000")

接著是controller層,就是api目錄。api目錄包括service文件夾和api下的文件。(注:一般來說controller層,service層是同級的,本項目其實api下的非service文件都是屬于controller層,所以還是同一層的,因為要遵守調用順序,不然可能會發生循環調用)。

/api/user.py文件

import logging
 
from bottle import request
#db數據庫引擎
from common.base import DB
#調用service層
from api.service.user import UserService
 
logger = logging.getLogger("arview")
 
 
class User(DB, UserService):
 
    def __init__(self, *args, **kwargs):
        print(">>> User init begin")
        logging.debug('>>> User init begin')
        super(User, self).__init__(*args, **kwargs)
        self.dispatch()
        logger.debug('>>> User init end')
 
    def create(self, db=None):
        create_body = request.json
        create_data = self.create_user(create_body, db)
        return create_data
 
    def delete(self, db=None):
        delete_body = request.json
        delete_data = self.delete_user(delete_body, db)
        return delete_data
 
    def list(self, db=None):
 
        list_data = self.list_user(db)
        return list_data
    #相當于分組路由
    def dispatch(self):
        self.app.route('/listUser', method='post')(self.list)
        self.app.route('/createUser', method='post')(self.create)
        self.app.route('/deleteUser', method='post')(self.delete)

/service/user.py

import time
#model層
from db.models.user import UserModel
 
 
class UserService(object):
    def list_user(self, db):
        user_info_list = db.query(UserModel).all()
        for item in user_info_list:
            print(item.username)
        return user_info_list
 
    def create_user(self, create_body, db):
        user_model = UserModel(
            username=create_body.get("username"),
            password=create_body.get("password"),
            role=create_body.get("role"),
            create_time=time.time()
        )
        db.add(user_model)
        db.commit()
        return "success"
 
    def delete_user(self, delete_body, db):
        db.query(UserModel).filter(UserModel.id == (delete_body["id"])).delete()
        db.commit()
        return delete_body

然后是dao層也就是數據庫操作層(但是明顯雖然有dao層但是數據庫操作的邏輯已經在service層里了)

最后是讀取配置文件和創建數據庫引擎。

讀取配置文件使用的包是oslo_config。

conf.py

# coding:utf8
# from __future__ import print_function
from oslo_config import cfg
 
DEFAULT_ARVIEW_DB_NAME = 'ginblog'
DEFAULT_ARVIEW_DB_USER = 'root'
DEFAULT_ARVIEW_DB_USER_PASSWORD = '33demysql'
DEFAULT_ARVIEW_DB_HOST = '81.68.179.136'
DEFAULT_ARVIEW_DB_PORT = 3306
DEFAULT_ARVIEW_DB_URL_TEMPLATE = 'mysql+mysqlconnector://{}:{}@' \

                                 '{}:{}/{}?charset=utf8'
DEFAULT_ARVIEW_DB_URL = DEFAULT_ARVIEW_DB_URL_TEMPLATE.format(
    DEFAULT_ARVIEW_DB_USER,
    DEFAULT_ARVIEW_DB_USER_PASSWORD,
    DEFAULT_ARVIEW_DB_HOST,
    DEFAULT_ARVIEW_DB_PORT,
    DEFAULT_ARVIEW_DB_NAME)
 
# 聲明參數選項
opt_group = cfg.OptGroup('keystone_authtoken')
mysql_opt_group = cfg.OptGroup('db')
 
auth_opts = [
    cfg.StrOpt('memcached_servers',
               default='localhost:11211',
               choices=("localhost:11211", "0.0.0.0:11211"),
               help=('localhost local', '0.0.0.0 So listen')
               ),
 
    cfg.StrOpt('signing_dir',
               default='/var/cache/cinder',
               choices=("/var/cache/cinder", "/var/cache/cinder"),
               ),
]
 
# mysql
mysql_opts = [
    cfg.StrOpt('url', default=DEFAULT_ARVIEW_DB_URL),
    cfg.StrOpt('Db', default='3mysql'),
    cfg.StrOpt('DbHost', default='381.68.179.136'),
    cfg.StrOpt('DbPort', default='33306'),
    cfg.StrOpt('DbUser', default='3DbUser'),
    cfg.StrOpt('DbPassWord', default='3DbPassWord'),
    cfg.StrOpt('DbName', default='3DbName'),
    cfg.BoolOpt('create', default=False),
    cfg.BoolOpt('commit', default=True),
    cfg.BoolOpt('echo', default=True, help='是否顯示回顯'),
    cfg.BoolOpt('echo_pool', default=False, help='數據庫連接池是否記錄 checkouts/checkins操作'),
    cfg.IntOpt('pool_size', default=1000, help='數據庫連接池中保持打開的連接數量'),
    cfg.IntOpt('pool_recycle', default=600, help='數據庫連接池在連接被創建多久(單位秒)以后回收連接')
]
 
token_opts = [
    cfg.StrOpt('project_domain_name'),
    cfg.StrOpt('project_name'),
]
 
CINDER_OPTS = (auth_opts +
               token_opts)
MYSQLCINDER_OPTS = (mysql_opts)
 
# 注冊參數選項
CONF = cfg.CONF
# 注冊組
CONF.register_group(opt_group)
CONF.register_group(mysql_opt_group)
 
# 將各個選項注冊進組里
CONF.register_opts(CINDER_OPTS, group=opt_group)
CONF.register_opts(MYSQLCINDER_OPTS, group=mysql_opt_group)
 
if __name__ == "__main__":
    # 要讀取哪個配置文件
    CONF(default_config_files=['cinder.conf'])
    print('mysql Db配置組為%s' % (CONF.db.Db))
    print('mysql DbHost%s' % (CONF.db.DbHost))
    print('mysql DbPort配置組為%s' % (CONF.db.DbPort))
    print('mysql DbUser%s' % (CONF.db.DbUser))

配置文件cinder.conf

[db]
Db = mysql
DbHost = 81.68.179.136
DbPort = 3306
DbUser = root
DbPassWord = 33demysql
DbName = ginblog
create = false
commit = true
echo = false
echo_pool = false
pool_size = 1000
pool_recycle =600

它的使用方法是,先聲明參數選項就是(相當于聲明組)

mysql_opt_group = cfg.OptGroup('db'),

然后聲明組內的選項,

mysql_opts = [
    cfg.StrOpt('url', default=DEFAULT_ARVIEW_DB_URL),
    cfg.StrOpt('Db', default='3mysql'),
    cfg.StrOpt('DbHost', default='381.68.179.136'),
    cfg.StrOpt('DbPort', default='33306'),
    cfg.StrOpt('DbUser', default='3DbUser'),
    cfg.StrOpt('DbPassWord', default='3DbPassWord'),
    cfg.StrOpt('DbName', default='3DbName'),
    cfg.BoolOpt('create', default=False),
    cfg.BoolOpt('commit', default=True),
    cfg.BoolOpt('echo', default=True, help='是否顯示回顯'),
    cfg.BoolOpt('echo_pool', default=False, help='數據庫連接池是否記錄 checkouts/checkins操作'),
    cfg.IntOpt('pool_size', default=1000, help='數據庫連接池中保持打開的連接數量'),
    cfg.IntOpt('pool_recycle', default=600, help='數據庫連接池在連接被創建多久(單位秒)以后回收連接')
]

拼接選項

MYSQLCINDER_OPTS = (mysql_opts)

接著注冊組,

CONF.register_group(mysql_opt_group)

最后將選項注冊進組。

CONF.register_opts(MYSQLCINDER_OPTS, group=mysql_opt_group)

當然最重要的注冊參數選項,我的理解就是暴露句柄。

# 注冊參數選項
CONF = cfg.CONF

然后創建數據庫引擎

common/utils/sqlalchemy_util.py

import logging
from json import loads as json_loads
 
from sqlalchemy.engine import create_engine
from sqlalchemy.pool import QueuePool
from confg import CONF
 
SQLALCHEMY_ENGINE_CONTAINER = {}
 
logger = logging.getLogger("arview")
 
 
def json_deserializer(s, **kw):
    if isinstance(s, bytes):
        return json_loads(s.decode('utf-8'), **kw)
 
    else:
        return json_loads(s, **kw)
 
 
def get_sqlalchemy_engine(db_url):
    if db_url not in SQLALCHEMY_ENGINE_CONTAINER:
        engine = create_engine(db_url, echo=CONF.db.echo,
                               # pool_pre_ping如果值為True,那么每次從連接池中拿連接的時候,都會向數據庫發送一個類似
                               # select 1的測試查詢語句來判斷服務器是否正常運行。當該連接出現disconnect的情況時,
                               # 該連接連同pool中的其它連接都會被回收
                               pool_pre_ping=True,
                               echo_pool=CONF.db.echo_pool,
                               pool_size=CONF.db.pool_size,
                               pool_recycle=CONF.db.pool_recycle,
                               json_deserializer=json_deserializer,
                               poolclass=QueuePool)
        logger.info('Create sqlalchemy engine %s', engine)
        SQLALCHEMY_ENGINE_CONTAINER[db_url] = engine
 
    return SQLALCHEMY_ENGINE_CONTAINER[db_url]

這里引用配置文件的數據,直接引入CONF

from confg import CONF

然后使用

CONF.db.echo_pool

創建句柄,

 與我之前使用的方法不同的是,這里的數據庫引擎不需要在使用的地方引入了,會在main里注冊路由分組時,通過plugin插件自動將數據庫引擎導入。這也是我有點搞不懂的地方,雖然更方便,但是不知道就很難知道了,問了同事才知道是怎么回事。

bottle源碼

def install(self, plugin):
    ''' Add a plugin to the list of plugins and prepare it for being
        applied to all routes of this application. A plugin may be a simple
        decorator or an object that implements the :class:`Plugin` API.
    '''

plugin就是相當與golang的中間件,不過作用范圍是全部路由。

這里創建數據庫句柄并使用是一個比較繞的過程。總體思路:

1.寫一個bottle plugin,創建數據庫句柄,然后install安裝這個plugin。就可以在所有的路由中自動引入這個插件(就是不用在包里在導入db句柄了,bottle會自動導入)。

/common/base.py 創建plugin并安裝

import logging
from bottle import Bottle
from confg.conf import CONF
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
from db.models.base import Base as ApiModelBase
from common.utils.sqlalchemy_util import get_sqlalchemy_engine
from bottle_sqlalchemy import SQLAlchemyPlugin
 
logger = logging.getLogger("arview")
base = ApiModelBase  # sqlalchemy orm base class
 
 
class Plugins:
    SQLALCHEMY_PLUGIN = None  # sqlalchemy plugin, global only one instance
    APSCHEDULER_PLUGIN = None  # apsechduler plugin. global only one instance
 
 
class Base(object):
    def __init__(self, *args, **kwargs):
        logger.debug('>>>> Base init begin')
        self.app = Bottle()
        # self.app.install(SwaggerPlugin(self._type))
 
        logger.debug('>>>> Base init end')
 
 
class DB(Base):
    def __init__(self, db_url, create=None, commit=None, *args, **kwargs):
        print('db_url:', db_url)
        super(DB, self).__init__(*args, **kwargs)
 
        if create is None:
            create = CONF.db.create
        if commit is None:
            commit = CONF.db.commit
 
        if Plugins.SQLALCHEMY_PLUGIN is None:
            Plugins.SQLALCHEMY_PLUGIN = _create_sqlalchemy_plugin(db_url, create=create, commit=commit)
        self.app.install(Plugins.SQLALCHEMY_PLUGIN)
        logger.debug("Install plugin: sqlalchemy.")
        # if CONF.api.enable_request_interval_plugin:
        #     self.app.install(RequestTimeIntervalPlugin())
        logger.debug('>>>> DB init end')
 
 
class CommonBase(object):
    def __init__(self):
        self._db = None
 
    @property
    def db(self):
        if not self._db:
            DBURL = "mysql+mysqlconnector://{}:{}@{}:{}/{}?charset=utf8".format(CONF.mysql.DbUser,
                                                                                CONF.mysql.DbPassWord,
                                                                                CONF.mysql.DbHost,
                                                                                CONF.mysql.DbPort,
                                                                                CONF.mysql.DbName)
            engine = create_engine(DBURL, echo=False)
            self._db = sessionmaker()(bind=engine)
        return self._db
 
    @db.deleter
    def db(self):
        if self._db:
            self._db.commit()
            self._db.close()
            self._db = None
 
 
def _create_sqlalchemy_plugin(db_url, create, commit):
    """
    創建sqlalchemy插件
    :param db_url:
    :param echo:
    :param create:
    :param commit:
    :return:
    """
 
    logger.debug('>>>> create sqlalchemy plugin begin')
    engine = get_sqlalchemy_engine(db_url)
    plugin = SQLAlchemyPlugin(engine, metadata=ApiModelBase.metadata, create=create, commit=commit, use_kwargs=True)
    logger.debug('>>>> create sqlalchemy plugin %s' % plugin)
    return plugin

最后使用

/api/user.py

import logging
 
from bottle import request
 
from common.base import DB
from api.service.user import UserService
 
logger = logging.getLogger("arview")
 
 
class User(DB, UserService):
 
    def __init__(self, *args, **kwargs):
        print(">>> User init begin")
        logging.debug('>>> User init begin')
        super(User, self).__init__(*args, **kwargs)
        self.dispatch()
        logger.debug('>>> User init end')
 
    def create(self, db=None):
        create_body = request.json
        create_data = self.create_user(create_body, db)
        return create_data
 
    def delete(self, db=None):
        delete_body = request.json
        delete_data = self.delete_user(delete_body, db)
        return delete_data
 
    def list(self, db=None):
 
        list_data = self.list_user(db)
        return list_data
 
    def dispatch(self):
        self.app.route('/listUser', method='post')(self.list)
        self.app.route('/createUser', method='post')(self.create)
        self.app.route('/deleteUser', method='post')(self.delete)

這里的db就不需要導入了,可以直接使用。

db層
主要是模型層 /db/model/user.py

from sqlalchemy import Column, String, Enum, TIMESTAMP, Boolean, Integer, BIGINT, DATETIME
 
from db.models.base import Base
 
 
class UserModel(Base):
    __tablename__ = "user"
    id = Column("id", BIGINT, primary_key=True, comment="用戶id")
    created_at = Column("created_at", DATETIME, comment="創建時間")
    updated_at = Column("updated_at", DATETIME, comment="更新時間")
    deleted_at = Column("deleted_at", DATETIME, comment="刪除時間")
    username = Column("username", String(20), comment="用戶名")
    password = Column("password", String(500), comment="密碼")
    role = Column("role", BIGINT, comment="角色")
 
    def __init__(self, id, created_at, updated_at, deleted_at, username, password, role):
        self.id = id
        self.created_at = created_at
        self.updated_at = updated_at
        self.deleted_at = deleted_at
        self.username = username
        self.password = password
        self.role = role

/db/model/base.py

from datetime import datetime
 
from sqlalchemy import Column, TIMESTAMP
from sqlalchemy.ext.declarative import declarative_base
 
 
# sqlalchemy orm base class
Base = declarative_base()
 
 
class TimestampMixin(object):
    """為ORM提供時間戳基類"""
 
    created_at = Column('created_at', TIMESTAMP(True), default=datetime.now,
                        comment=u"創建時間")
    updated_at = Column('updated_at', TIMESTAMP(True), default=datetime.now,
                        onupdate=datetime.now, comment=u"更新時間")

到此這篇關于python bottle使用實例的文章就介紹到這了,更多相關python bottle使用內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python使用Py2neo創建Neo4j的節點、關系及路徑
  • Python使用py2neo操作圖數據庫neo4j的方法詳解
  • python利用文件讀寫編寫一個博客
  • 手把手帶你用python爬取小姐姐私房照
  • Python time.time()方法
  • Python接口自動化之接口依賴
  • python使用py2neo查詢Neo4j的節點、關系及路徑

標簽:普洱 林芝 盤錦 大同 南平 漯河 寧夏 海南

巨人網絡通訊聲明:本文標題《python中bottle使用實例代碼》,本文關鍵詞  python,中,bottle,使用,實例,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《python中bottle使用實例代碼》相關的同類信息!
  • 本頁收集關于python中bottle使用實例代碼的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产精品一区在线| 色视频欧美一区二区三区| 最新国产成人在线观看| 欧美日韩中文精品| 成熟亚洲日本毛茸茸凸凹| 午夜天堂影视香蕉久久| 国产精品无人区| 欧美成人在线直播| 欧美在线影院一区二区| 成人在线视频一区| 另类人妖一区二区av| 亚洲色欲色欲www| 国产日产欧美精品一区二区三区| 欧美精品日韩一区| 色天天综合色天天久久| 成人天堂资源www在线| 老司机精品视频一区二区三区| 亚洲国产你懂的| 亚洲欧美日韩中文播放 | 老司机精品视频一区二区三区| 日韩码欧中文字| 国产亚洲一本大道中文在线| 欧美一区国产二区| 欧美精品久久99| 欧美写真视频网站| 欧美综合天天夜夜久久| 99国产欧美另类久久久精品| 国产一区二区三区在线观看精品 | 蜜臀av在线播放一区二区三区| 日本一二三四高清不卡| 欧美一区二区精品久久911| 91女神在线视频| 国产一区二区三区免费在线观看| 丝袜诱惑制服诱惑色一区在线观看 | 欧美性做爰猛烈叫床潮| 不卡一卡二卡三乱码免费网站| 久久99精品一区二区三区三区| 亚洲一区二区av电影| 亚洲色欲色欲www| 中文乱码免费一区二区| 2022国产精品视频| 欧美一二三在线| 欧美美女一区二区| 欧美性做爰猛烈叫床潮| 在线一区二区观看| 色综合视频在线观看| 99精品久久只有精品| 懂色av中文一区二区三区| 狠狠色丁香久久婷婷综合丁香| 丝袜亚洲另类欧美综合| 五月婷婷综合激情| 亚洲国产精品久久久久秋霞影院| 亚洲欧美区自拍先锋| 亚洲精品免费一二三区| 亚洲乱码国产乱码精品精98午夜| 国产欧美精品一区| 国产精品色婷婷| 国产欧美精品一区二区色综合| 国产三级一区二区三区| 国产日韩影视精品| 国产精品美女久久久久aⅴ| 久久免费偷拍视频| 久久精品视频免费观看| 2014亚洲片线观看视频免费| 久久久久久久久久电影| 国产欧美精品一区二区色综合| 国产拍揄自揄精品视频麻豆| 国产精品色哟哟| 日韩美女视频一区二区| 亚洲成人精品影院| 精品中文字幕一区二区| 久久成人免费电影| 国产乱码精品1区2区3区| 成人免费三级在线| 色综合久久久网| 欧美日本一道本| 2024国产精品| 亚洲欧美成人一区二区三区| 午夜久久电影网| 国内外成人在线视频| 成人伦理片在线| 欧洲视频一区二区| 日韩欧美久久一区| 国产精品久久久久久亚洲伦| 亚洲综合免费观看高清在线观看| 亚洲一区中文在线| 国产自产v一区二区三区c| 波多野结衣在线一区| 色狠狠综合天天综合综合| 欧美一a一片一级一片| 欧美一级免费大片| 欧美国产97人人爽人人喊| 亚洲国产毛片aaaaa无费看 | 成人在线一区二区三区| 91福利国产成人精品照片| 日韩欧美高清一区| 国产精品国产三级国产aⅴ原创 | 另类小说视频一区二区| av男人天堂一区| 欧美一区二区三区系列电影| 久久精品视频免费观看| 亚洲超碰精品一区二区| 国产成人在线电影| 一本久道久久综合中文字幕 | 欧美日韩情趣电影| 国产亚洲欧美日韩俺去了| 一区二区三区精密机械公司| 国产一区二区三区香蕉| 欧美系列在线观看| 国产精品理论片在线观看| 日本欧美一区二区三区乱码| av网站一区二区三区| 欧美videos中文字幕| 亚洲精品免费播放| 国产大片一区二区| 91精品国产综合久久久久久 | 国产精品色婷婷久久58| 日韩不卡一二三区| 色婷婷综合久久久久中文| 欧美一区二区视频在线观看2020| 久久久精品中文字幕麻豆发布| 亚洲在线视频网站| 99久久精品费精品国产一区二区| 精品女同一区二区| 亚洲高清三级视频| www.久久精品| 26uuu国产电影一区二区| 欧美激情一区二区三区不卡| 另类小说色综合网站| 欧美美女视频在线观看| 亚洲综合一区在线| 成人免费毛片高清视频| 欧美大尺度电影在线| 亚洲v日本v欧美v久久精品| 91免费精品国自产拍在线不卡| 久久精品免费在线观看| 精品一区二区在线看| 欧美在线免费视屏| 精品欧美一区二区在线观看| 亚洲福利一二三区| 欧美天天综合网| 一区二区三区毛片| 色综合久久99| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 国精品**一区二区三区在线蜜桃| 日韩欧美黄色影院| 老司机免费视频一区二区| 日韩一区二区麻豆国产| 奇米四色…亚洲| 精品视频在线看| 丝袜美腿亚洲综合| 欧美老肥妇做.爰bbww视频| 亚洲一区二区欧美| 欧美丰满少妇xxxxx高潮对白| 午夜精品成人在线| 欧美美女网站色| 免费成人美女在线观看.| 日韩一区二区在线免费观看| 秋霞午夜鲁丝一区二区老狼| 91精品蜜臀在线一区尤物| 日韩av在线发布| 777奇米成人网| 青青青爽久久午夜综合久久午夜| 91精品国产综合久久久蜜臀粉嫩| 亚洲一区二区三区国产| 91精品久久久久久久99蜜桃 | 成人免费视频免费观看| 亚洲视频中文字幕| 在线观看网站黄不卡| 三级成人在线视频| 精品欧美久久久| 成人网在线播放| 亚洲精品免费一二三区| 91精品啪在线观看国产60岁| 麻豆极品一区二区三区| 国产日韩v精品一区二区| 91网址在线看| 日韩 欧美一区二区三区| 精品日韩一区二区三区| 波多野结衣亚洲| 午夜成人免费电影| 久久综合一区二区| 9人人澡人人爽人人精品| 国产精品不卡在线| 日韩一区二区免费视频| 成人a免费在线看| 亚洲成av人综合在线观看| 欧美精品18+| 国产精品一品二品| 亚洲色图另类专区| 欧美日韩国产在线观看| 国产成人av在线影院| 亚洲一区二区三区四区中文字幕| 欧美一区二区三区在线电影| 成人国产精品免费观看视频| 亚洲高清视频在线| 国产精品丝袜在线| 日本精品一区二区三区高清| 久久99精品视频| 一区二区三区中文在线观看|