如何使此代码成为模块

Posted

技术标签:

【中文标题】如何使此代码成为模块【英文标题】:how to make this code to become module 【发布时间】:2018-08-30 07:19:22 【问题描述】:

这是 Python 代码code

import os
import base64
from io import BytesIO
from flask import Flask, render_template, redirect, url_for, flash, session, \
    abort
from werkzeug.security import generate_password_hash, check_password_hash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, logout_user, \
    current_user
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import Required, Length, EqualTo
import onetimepass
import pyqrcode

# create application instance
app = Flask(__name__)
app.config.from_object('config')

# initialize extensions
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
lm = LoginManager(app)


class User(UserMixin, db.Model):
    """User model."""
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True)
    password_hash = db.Column(db.String(128))
    otp_secret = db.Column(db.String(16))

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
        if self.otp_secret is None:
            # generate a random secret
            self.otp_secret = base64.b32encode(os.urandom(10)).decode('utf-8')

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def get_totp_uri(self):
        return 'otpauth://totp/2FA-Demo:0?secret=1&issuer=2FA-Demo' \
            .format(self.username, self.otp_secret)

    def verify_totp(self, token):
        return onetimepass.valid_totp(token, self.otp_secret)


@lm.user_loader
def load_user(user_id):
    """User loader callback for Flask-Login."""
    return User.query.get(int(user_id))


class RegisterForm(FlaskForm):
    """Registration form."""
    username = StringField('Username', validators=[Required(), Length(1, 64)])
    password = PasswordField('Password', validators=[Required()])
    password_again = PasswordField('Password again',
                                   validators=[Required(), EqualTo('password')])
    submit = SubmitField('Register')


class LoginForm(FlaskForm):
    """Login form."""
    username = StringField('Username', validators=[Required(), Length(1, 64)])
    password = PasswordField('Password', validators=[Required()])
    token = StringField('Token', validators=[Required(), Length(6, 6)])
    submit = SubmitField('Login')


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/register', methods=['GET', 'POST'])
def register():
    """User registration route."""
    if current_user.is_authenticated:
        # if user is logged in we get out of here
        return redirect(url_for('index'))
    form = RegisterForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is not None:
            flash('Username already exists.')
            return redirect(url_for('register'))
        # add new user to the database
        user = User(username=form.username.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()

        # redirect to the two-factor auth page, passing username in session
        session['username'] = user.username
        return redirect(url_for('two_factor_setup'))
    return render_template('register.html', form=form)


@app.route('/twofactor')
def two_factor_setup():
    if 'username' not in session:
        return redirect(url_for('index'))
    user = User.query.filter_by(username=session['username']).first()
    if user is None:
        return redirect(url_for('index'))
    # since this page contains the sensitive qrcode, make sure the browser
    # does not cache it
    return render_template('two-factor-setup.html'), 200, 
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'


@app.route('/qrcode')
def qrcode():
    if 'username' not in session:
        abort(404)
    user = User.query.filter_by(username=session['username']).first()
    if user is None:
        abort(404)

    # for added security, remove username from session
    del session['username']

    # render qrcode for FreeTOTP
    url = pyqrcode.create(user.get_totp_uri())
    stream = BytesIO()
    url.svg(stream, scale=3)
    return stream.getvalue(), 200, 
        'Content-Type': 'image/svg+xml',
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'


@app.route('/login', methods=['GET', 'POST'])
def login():
    """User login route."""
    if current_user.is_authenticated:
        # if user is logged in we get out of here
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user is None or not user.verify_password(form.password.data) or \
                not user.verify_totp(form.token.data):
            flash('Invalid username, password or token.')
            return redirect(url_for('login'))

        # log user in
        login_user(user)
        flash('You are now logged in!')
        return redirect(url_for('index'))
    return render_template('login.html', form=form)


@app.route('/logout')
def logout():
    """User logout route."""
    logout_user()
    return redirect(url_for('index'))


# create database tables if they don't exist yet
db.create_all()


if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

我试图将它拆分为一个模块,但它不起作用。

我正在命名 auth.py 并且我正在尝试在 views.py 上添加用于登录和注册的路由,但没有成功我正在关注这个 example 但是

如果我必须将所有导入从 auth.py 导入到 views.py,你能解释一下如何拆分它吗?

【问题讨论】:

添加注释尝试将代码粘贴到此处而不是链接中... 你能解释一下,因为当我试图粘贴它时,它看起来像一场灾难,这就是我链接代码的原因 将您的代码粘贴到您的文件中,然后全选并按 CTRL+K 。 除非您使用 按钮将其标记为代码,否则它看起来就像一场灾难。 我已经完成了,没有人说要粘贴代码以选择它,然后按下 按钮,每个人都说要使用 按钮:( 【参考方案1】:

根据docs,模块是包含 Python 定义和语句的文件。文件名是后缀.py的模块名。

您只需使用import moduleNameHere即可导入模块。

您的问题可能是您想要创建一个包,而不是一个模块。同样,根据docs,包是一种通过使用“带点的模块名称”来构建 Python 模块命名空间的方式。例如,模块名称 AB 指定了一个名为 A 的包中的一个名为 B 的子模块。就像使用模块使不同模块的作者不必担心彼此的全局变量名称一样,使用点分模块名称可以节省作者多模块包(如 NumPy 或 Python Imaging Library)不必担心彼此的模块名称。

创建包的最简单方法是在与要打包的脚本相同的目录中创建一个名为__init__.py 的文件打包

您可以查看this answer 了解更多详情。但基本上如果你想要一个名为hello*** 的包,你应该有一个像这样的目录结构:

.
└── hello***/
    ├── __init__.py
    └── hello***.py

祝你好运!

【讨论】:

以上是关于如何使此代码成为模块的主要内容,如果未能解决你的问题,请参考以下文章

如何使此代码适用于更大的数字?

如何使此 Java 代码正常运行? [多线程,竞争条件]

如何使此代码与 react-router v6 兼容

如何使此代码在单个文件夹中运行多个图像?

如何使此代码与 Integer-> Int 类型签名一起使用?

如何使此代码运行得更好/更快(线程或多处理)?怎么做?