- 新增图像生成接口,支持试用、积分和自定义API Key模式 - 实现生成图片结果异步上传至MinIO存储,带重试机制 - 优化积分预扣除和异常退还逻辑,保障用户积分准确 - 添加获取生成历史记录接口,支持时间范围和分页 - 提供本地字典配置接口,支持模型、比例、提示模板和尺寸 - 实现图片批量上传接口,支持S3兼容对象存储 feat(admin): 增加管理员角色管理与权限分配接口 - 实现角色列表查询、角色创建、更新及删除功能 - 增加权限列表查询接口 - 实现用户角色分配接口,便于统一管理用户权限 - 增加系统字典增删查改接口,支持分类过滤和排序 - 权限控制全面覆盖管理接口,保证安全访问 feat(auth): 完善用户登录注册及权限相关接口与页面 - 实现手机号验证码发送及校验功能,保障注册安全 - 支持手机号注册、登录及退出接口,集成日志记录 - 增加修改密码功能,验证原密码后更新 - 提供动态导航菜单接口,基于权限展示不同菜单 - 实现管理界面路由及日志、角色、字典管理页面访问权限控制 - 添加系统日志查询接口,支持关键词和等级筛选 feat(app): 初始化Flask应用并配置蓝图与数据库 - 创建应用程序工厂,加载配置,初始化数据库和Redis客户端 - 注册认证、API及管理员蓝图,整合路由 - 根路由渲染主页模板 - 应用上下文中自动创建数据库表,保证运行环境准备完毕 feat(database): 提供数据库创建与迁移支持脚本 - 新增数据库创建脚本,支持自动检测是否已存在 - 添加数据库表初始化脚本,支持创建和删除所有表 - 实现RBAC权限初始化,包含基础权限和角色创建 - 新增字段手动修复脚本,添加用户API Key和积分字段 - 强制迁移脚本支持清理连接和修复表结构,初始化默认数据及角色分配 feat(config): 新增系统配置参数 - 配置数据库、Redis、Session和MinIO相关参数 - 添加AI接口地址及试用Key配置 - 集成阿里云短信服务配置及开发模式相关参数 feat(extensions): 初始化数据库、Redis和MinIO客户端 - 创建全局SQLAlchemy数据库实例和Redis客户端 - 配置基于boto3的MinIO兼容S3客户端 chore(logs): 添加示例系统日志文件 - 记录用户请求、验证码发送成功与失败的日志信息
478 lines
20 KiB
Python
478 lines
20 KiB
Python
# Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
|
# may not use this file except in compliance with the License. A copy of
|
|
# the License is located at
|
|
#
|
|
# http://aws.amazon.com/apache2.0/
|
|
#
|
|
# or in the "license" file accompanying this file. This file is
|
|
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
# ANY KIND, either express or implied. See the License for the specific
|
|
# language governing permissions and limitations under the License.
|
|
import copy
|
|
|
|
from botocore.compat import OrderedDict
|
|
from botocore.endpoint import DEFAULT_TIMEOUT, MAX_POOL_CONNECTIONS
|
|
from botocore.exceptions import (
|
|
InvalidMaxRetryAttemptsError,
|
|
InvalidRetryConfigurationError,
|
|
InvalidRetryModeError,
|
|
InvalidS3AddressingStyleError,
|
|
)
|
|
|
|
|
|
class Config:
|
|
"""Advanced configuration for Botocore clients.
|
|
|
|
:type region_name: str
|
|
:param region_name: The region to use in instantiating the client
|
|
|
|
:type signature_version: str
|
|
:param signature_version: The signature version when signing requests.
|
|
|
|
:type user_agent: str
|
|
:param user_agent: The value to use in the User-Agent header.
|
|
|
|
:type user_agent_extra: str
|
|
:param user_agent_extra: The value to append to the current User-Agent
|
|
header value.
|
|
|
|
:type user_agent_appid: str
|
|
:param user_agent_appid: A value that gets included in the User-Agent
|
|
string in the format "app/<user_agent_appid>". Allowed characters are
|
|
ASCII alphanumerics and ``!#$%&'*+-.^_`|~``. All other characters will
|
|
be replaced by a ``-``.
|
|
|
|
:type connect_timeout: float or int
|
|
:param connect_timeout: The time in seconds till a timeout exception is
|
|
thrown when attempting to make a connection. The default is 60
|
|
seconds.
|
|
|
|
:type read_timeout: float or int
|
|
:param read_timeout: The time in seconds till a timeout exception is
|
|
thrown when attempting to read from a connection. The default is
|
|
60 seconds.
|
|
|
|
:type parameter_validation: bool
|
|
:param parameter_validation: Whether parameter validation should occur
|
|
when serializing requests. The default is True. You can disable
|
|
parameter validation for performance reasons. Otherwise, it's
|
|
recommended to leave parameter validation enabled.
|
|
|
|
:type max_pool_connections: int
|
|
:param max_pool_connections: The maximum number of connections to
|
|
keep in a connection pool. If this value is not set, the default
|
|
value of 10 is used.
|
|
|
|
:type proxies: dict
|
|
:param proxies: A dictionary of proxy servers to use by protocol or
|
|
endpoint, e.g.:
|
|
``{'http': 'foo.bar:3128', 'http://hostname': 'foo.bar:4012'}``.
|
|
The proxies are used on each request.
|
|
|
|
:type proxies_config: dict
|
|
:param proxies_config: A dictionary of additional proxy configurations.
|
|
Valid keys are:
|
|
|
|
* ``proxy_ca_bundle`` -- The path to a custom certificate bundle to use
|
|
when establishing SSL/TLS connections with proxy.
|
|
|
|
* ``proxy_client_cert`` -- The path to a certificate for proxy
|
|
TLS client authentication.
|
|
|
|
When a string is provided it is treated as a path to a proxy client
|
|
certificate. When a two element tuple is provided, it will be
|
|
interpreted as the path to the client certificate, and the path
|
|
to the certificate key.
|
|
|
|
* ``proxy_use_forwarding_for_https`` -- For HTTPS proxies,
|
|
forward your requests to HTTPS destinations with an absolute
|
|
URI. We strongly recommend you only use this option with
|
|
trusted or corporate proxies. Value must be boolean.
|
|
|
|
:type s3: dict
|
|
:param s3: A dictionary of S3 specific configurations.
|
|
Valid keys are:
|
|
|
|
* ``use_accelerate_endpoint`` -- Refers to whether to use the S3
|
|
Accelerate endpoint. The value must be a boolean. If True, the
|
|
client will use the S3 Accelerate endpoint. If the S3 Accelerate
|
|
endpoint is being used then the addressing style will always
|
|
be virtual.
|
|
|
|
* ``payload_signing_enabled`` -- Refers to whether or not to SHA256
|
|
sign SigV4 payloads. For operations that support request checksums,
|
|
this only applies when ``request_checksum_calculation`` is set to
|
|
``when_required``. Otherwise, this is disabled for
|
|
streaming uploads (UploadPart and PutObject) by default.
|
|
|
|
* ``addressing_style`` -- Refers to the style in which to address
|
|
s3 endpoints. Values must be a string that equals one of:
|
|
|
|
* ``auto`` -- Addressing style is chosen for user. Depending
|
|
on the configuration of client, the endpoint may be addressed in
|
|
the virtual or the path style. Note that this is the default
|
|
behavior if no style is specified.
|
|
|
|
* ``virtual`` -- Addressing style is always virtual. The name of the
|
|
bucket must be DNS compatible or an exception will be thrown.
|
|
Endpoints will be addressed as such: ``amzn-s3-demo-bucket.s3.amazonaws.com``
|
|
|
|
* ``path`` -- Addressing style is always by path. Endpoints will be
|
|
addressed as such: ``s3.amazonaws.com/amzn-s3-demo-bucket``
|
|
|
|
* ``us_east_1_regional_endpoint`` -- Refers to what S3 endpoint to use
|
|
when the region is configured to be us-east-1. Values must be a
|
|
string that equals:
|
|
|
|
* ``regional`` -- Use the us-east-1.amazonaws.com endpoint if the
|
|
client is configured to use the us-east-1 region.
|
|
|
|
* ``legacy`` -- Use the s3.amazonaws.com endpoint if the client is
|
|
configured to use the us-east-1 region. This is the default if
|
|
the configuration option is not specified.
|
|
|
|
|
|
:type retries: dict
|
|
:param retries: A dictionary for configuration related to retry behavior.
|
|
Valid keys are:
|
|
|
|
* ``total_max_attempts`` -- An integer representing the maximum number of
|
|
total attempts that will be made on a single request. This includes
|
|
the initial request, so a value of 1 indicates that no requests
|
|
will be retried. If ``total_max_attempts`` and ``max_attempts``
|
|
are both provided, ``total_max_attempts`` takes precedence.
|
|
``total_max_attempts`` is preferred over ``max_attempts`` because
|
|
it maps to the ``AWS_MAX_ATTEMPTS`` environment variable and
|
|
the ``max_attempts`` config file value.
|
|
* ``max_attempts`` -- An integer representing the maximum number of
|
|
retry attempts that will be made on a single request. For
|
|
example, setting this value to 2 will result in the request
|
|
being retried at most two times after the initial request. Setting
|
|
this value to 0 will result in no retries ever being attempted after
|
|
the initial request. If not provided, the number of retries will
|
|
default to the value specified in the service model, which is
|
|
typically four retries.
|
|
* ``mode`` -- A string representing the type of retry mode botocore
|
|
should use. Valid values are:
|
|
|
|
* ``legacy`` - The pre-existing retry behavior.
|
|
|
|
* ``standard`` - The standardized set of retry rules. This will also
|
|
default to 3 max attempts unless overridden.
|
|
|
|
* ``adaptive`` - Retries with additional client side throttling.
|
|
|
|
:type client_cert: str, (str, str)
|
|
:param client_cert: The path to a certificate for TLS client authentication.
|
|
|
|
When a string is provided it is treated as a path to a client
|
|
certificate to be used when creating a TLS connection.
|
|
|
|
If a client key is to be provided alongside the client certificate the
|
|
client_cert should be set to a tuple of length two where the first
|
|
element is the path to the client certificate and the second element is
|
|
the path to the certificate key.
|
|
|
|
:type inject_host_prefix: bool
|
|
:param inject_host_prefix: Whether host prefix injection should occur.
|
|
|
|
Defaults to None.
|
|
|
|
The default of None is equivalent to setting to True, which enables
|
|
the injection of operation parameters into the prefix of the hostname.
|
|
Setting this to False disables the injection of operation parameters
|
|
into the prefix of the hostname. Setting this to False is useful for
|
|
clients providing custom endpoints that should not have their host
|
|
prefix modified.
|
|
|
|
:type use_dualstack_endpoint: bool
|
|
:param use_dualstack_endpoint: Setting to True enables dualstack
|
|
endpoint resolution.
|
|
|
|
Defaults to None.
|
|
|
|
:type use_fips_endpoint: bool
|
|
:param use_fips_endpoint: Setting to True enables fips
|
|
endpoint resolution.
|
|
|
|
Defaults to None.
|
|
|
|
:type ignore_configured_endpoint_urls: bool
|
|
:param ignore_configured_endpoint_urls: Setting to True disables use
|
|
of endpoint URLs provided via environment variables and
|
|
the shared configuration file.
|
|
|
|
Defaults to None.
|
|
|
|
:type tcp_keepalive: bool
|
|
:param tcp_keepalive: Enables the TCP Keep-Alive socket option used when
|
|
creating new connections if set to True.
|
|
|
|
Defaults to False.
|
|
|
|
:type request_min_compression_size_bytes: int
|
|
:param request_min_compression_size_bytes: The minimum size in bytes that a
|
|
request body should be to trigger compression. All requests with
|
|
streaming input that don't contain the ``requiresLength`` trait will be
|
|
compressed regardless of this setting.
|
|
|
|
Defaults to None.
|
|
|
|
:type disable_request_compression: bool
|
|
:param disable_request_compression: Disables request body compression if
|
|
set to True.
|
|
|
|
Defaults to None.
|
|
|
|
:type sigv4a_signing_region_set: string
|
|
:param sigv4a_signing_region_set: A set of AWS regions to apply the signature for
|
|
when using SigV4a for signing. Set to ``*`` to represent all regions.
|
|
|
|
Defaults to None.
|
|
|
|
:type client_context_params: dict
|
|
:param client_context_params: A dictionary of parameters specific to
|
|
individual services. If available, valid parameters can be found in
|
|
the ``Client Context Parameters`` section of the service client's
|
|
documentation. Invalid parameters or ones that are not used by the
|
|
specified service will be ignored.
|
|
|
|
Defaults to None.
|
|
|
|
:type request_checksum_calculation: str
|
|
:param request_checksum_calculation: Determines when a checksum will be
|
|
calculated for request payloads. Valid values are:
|
|
|
|
* ``when_supported`` -- When set, a checksum will be calculated for
|
|
all request payloads of operations modeled with the ``httpChecksum``
|
|
trait where ``requestChecksumRequired`` is ``true`` or a
|
|
``requestAlgorithmMember`` is modeled.
|
|
|
|
* ``when_required`` -- When set, a checksum will only be calculated
|
|
for request payloads of operations modeled with the ``httpChecksum``
|
|
trait where ``requestChecksumRequired`` is ``true`` or where a
|
|
``requestAlgorithmMember`` is modeled and supplied.
|
|
|
|
Defaults to None.
|
|
|
|
:type response_checksum_validation: str
|
|
:param response_checksum_validation: Determines when checksum validation
|
|
will be performed on response payloads. Valid values are:
|
|
|
|
* ``when_supported`` -- When set, checksum validation is performed on
|
|
all response payloads of operations modeled with the ``httpChecksum``
|
|
trait where ``responseAlgorithms`` is modeled, except when no modeled
|
|
checksum algorithms are supported.
|
|
|
|
* ``when_required`` -- When set, checksum validation is not performed
|
|
on response payloads of operations unless the checksum algorithm is
|
|
supported and the ``requestValidationModeMember`` member is set to ``ENABLED``.
|
|
|
|
Defaults to None.
|
|
|
|
:type account_id_endpoint_mode: str
|
|
:param account_id_endpoint_mode: The value used to determine the client's
|
|
behavior for account ID based endpoint routing. Valid values are:
|
|
|
|
* ``preferred`` - The endpoint should include account ID if available.
|
|
* ``disabled`` - A resolved endpoint does not include account ID.
|
|
* ``required`` - The endpoint must include account ID. If the account ID
|
|
isn't available, an exception will be raised.
|
|
|
|
If a value is not provided, the client will default to ``preferred``.
|
|
|
|
Defaults to None.
|
|
|
|
:type auth_scheme_preference: str
|
|
:param auth_scheme_preference: A comma-delimited string of case-sensitive
|
|
auth scheme names used to determine the client's auth scheme preference.
|
|
|
|
Defaults to None.
|
|
"""
|
|
|
|
OPTION_DEFAULTS = OrderedDict(
|
|
[
|
|
('region_name', None),
|
|
('signature_version', None),
|
|
('user_agent', None),
|
|
('user_agent_extra', None),
|
|
('user_agent_appid', None),
|
|
('connect_timeout', DEFAULT_TIMEOUT),
|
|
('read_timeout', DEFAULT_TIMEOUT),
|
|
('parameter_validation', True),
|
|
('max_pool_connections', MAX_POOL_CONNECTIONS),
|
|
('proxies', None),
|
|
('proxies_config', None),
|
|
('s3', None),
|
|
('retries', None),
|
|
('client_cert', None),
|
|
('inject_host_prefix', None),
|
|
('endpoint_discovery_enabled', None),
|
|
('use_dualstack_endpoint', None),
|
|
('use_fips_endpoint', None),
|
|
('ignore_configured_endpoint_urls', None),
|
|
('defaults_mode', None),
|
|
('tcp_keepalive', None),
|
|
('request_min_compression_size_bytes', None),
|
|
('disable_request_compression', None),
|
|
('client_context_params', None),
|
|
('sigv4a_signing_region_set', None),
|
|
('request_checksum_calculation', None),
|
|
('response_checksum_validation', None),
|
|
('account_id_endpoint_mode', None),
|
|
('auth_scheme_preference', None),
|
|
]
|
|
)
|
|
|
|
NON_LEGACY_OPTION_DEFAULTS = {
|
|
'connect_timeout': None,
|
|
}
|
|
|
|
# The original default value of the inject_host_prefix parameter was True.
|
|
# This prevented the ability to override the value from other locations in
|
|
# the parameter provider chain, like env vars or the shared configuration
|
|
# file. TO accomplish this, we need to disambiguate when the value was set
|
|
# by the user or not. This overrides the parameter with a property so the
|
|
# default value of inject_host_prefix is still True if it is not set by the
|
|
# user.
|
|
@property
|
|
def inject_host_prefix(self):
|
|
if self._inject_host_prefix == "UNSET":
|
|
return True
|
|
|
|
return self._inject_host_prefix
|
|
|
|
# Override the setter for the case where the user does supply a value;
|
|
# _inject_host_prefix will no longer be "UNSET".
|
|
@inject_host_prefix.setter
|
|
def inject_host_prefix(self, value):
|
|
self._inject_host_prefix = value
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self._user_provided_options = self._record_user_provided_options(
|
|
args, kwargs
|
|
)
|
|
|
|
# By default, we use a value that indicates the user did not
|
|
# set it. This value MUST persist on the Config object to be used
|
|
# elsewhere.
|
|
self._inject_host_prefix = 'UNSET'
|
|
|
|
# Merge the user_provided options onto the default options
|
|
config_vars = copy.copy(self.OPTION_DEFAULTS)
|
|
defaults_mode = self._user_provided_options.get(
|
|
'defaults_mode', 'legacy'
|
|
)
|
|
if defaults_mode != 'legacy':
|
|
config_vars.update(self.NON_LEGACY_OPTION_DEFAULTS)
|
|
|
|
config_vars.update(self._user_provided_options)
|
|
|
|
# Set the attributes based on the config_vars
|
|
for key, value in config_vars.items():
|
|
# Default values for the Config object are set here. We don't want
|
|
# to use `setattr` in the case where the user already supplied a
|
|
# value.
|
|
if (
|
|
key == 'inject_host_prefix'
|
|
and 'inject_host_prefix'
|
|
not in self._user_provided_options.keys()
|
|
):
|
|
continue
|
|
setattr(self, key, value)
|
|
|
|
# Validate the s3 options
|
|
self._validate_s3_configuration(self.s3)
|
|
|
|
self._validate_retry_configuration(self.retries)
|
|
|
|
def _record_user_provided_options(self, args, kwargs):
|
|
option_order = list(self.OPTION_DEFAULTS)
|
|
user_provided_options = {}
|
|
|
|
# Iterate through the kwargs passed through to the constructor and
|
|
# map valid keys to the dictionary
|
|
for key, value in kwargs.items():
|
|
if key in self.OPTION_DEFAULTS:
|
|
user_provided_options[key] = value
|
|
# The key must exist in the available options
|
|
else:
|
|
raise TypeError(f"Got unexpected keyword argument '{key}'")
|
|
|
|
# The number of args should not be longer than the allowed
|
|
# options
|
|
if len(args) > len(option_order):
|
|
raise TypeError(
|
|
f"Takes at most {len(option_order)} arguments ({len(args)} given)"
|
|
)
|
|
|
|
# Iterate through the args passed through to the constructor and map
|
|
# them to appropriate keys.
|
|
for i, arg in enumerate(args):
|
|
# If a kwarg was specified for the arg, then error out
|
|
if option_order[i] in user_provided_options:
|
|
raise TypeError(
|
|
f"Got multiple values for keyword argument '{option_order[i]}'"
|
|
)
|
|
user_provided_options[option_order[i]] = arg
|
|
|
|
return user_provided_options
|
|
|
|
def _validate_s3_configuration(self, s3):
|
|
if s3 is not None:
|
|
addressing_style = s3.get('addressing_style')
|
|
if addressing_style not in ['virtual', 'auto', 'path', None]:
|
|
raise InvalidS3AddressingStyleError(
|
|
s3_addressing_style=addressing_style
|
|
)
|
|
|
|
def _validate_retry_configuration(self, retries):
|
|
valid_options = ('max_attempts', 'mode', 'total_max_attempts')
|
|
valid_modes = ('legacy', 'standard', 'adaptive')
|
|
if retries is not None:
|
|
for key, value in retries.items():
|
|
if key not in valid_options:
|
|
raise InvalidRetryConfigurationError(
|
|
retry_config_option=key,
|
|
valid_options=valid_options,
|
|
)
|
|
if key == 'max_attempts' and value < 0:
|
|
raise InvalidMaxRetryAttemptsError(
|
|
provided_max_attempts=value,
|
|
min_value=0,
|
|
)
|
|
if key == 'total_max_attempts' and value < 1:
|
|
raise InvalidMaxRetryAttemptsError(
|
|
provided_max_attempts=value,
|
|
min_value=1,
|
|
)
|
|
if key == 'mode' and value not in valid_modes:
|
|
raise InvalidRetryModeError(
|
|
provided_retry_mode=value,
|
|
valid_modes=valid_modes,
|
|
)
|
|
|
|
def merge(self, other_config):
|
|
"""Merges the config object with another config object
|
|
|
|
This will merge in all non-default values from the provided config
|
|
and return a new config object
|
|
|
|
:type other_config: botocore.config.Config
|
|
:param other config: Another config object to merge with. The values
|
|
in the provided config object will take precedence in the merging
|
|
|
|
:returns: A config object built from the merged values of both
|
|
config objects.
|
|
"""
|
|
# Make a copy of the current attributes in the config object.
|
|
config_options = copy.copy(self._user_provided_options)
|
|
|
|
# Merge in the user provided options from the other config
|
|
config_options.update(other_config._user_provided_options)
|
|
|
|
# Return a new config object with the merged properties.
|
|
return Config(**config_options)
|