相关依赖
- Python3
- Flask
- MySQL
创建文件flask_short_link.py,整个应用只有这一个文件,去除空格代码在30行左右。
应用配置
导入相关依赖。
# 导入所需的模块
import random
import re
from datetime import datetime
from flask import Flask
from flask import request, abort, redirect
from flask_sqlalchemy import SQLAlchemy
定义配置,实例化应用对象以及数据库对象。
# 配置
class AppConfig:
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:root@localhost/test"
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
# 实例化Flask和数据库对象
app = Flask(__name__)
app.config.from_object(AppConfig())
db = SQLAlchemy(app)
- SQLALCHEMY_DATABASE_URI 是flask的数据库连接,注意这里换成你自己的配置。
- SQLALCHEMY_TRACK_MODIFICATIONS 如果设置成 True (默认情况),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。这需要额外的内存, 如果不必要的可以禁用它。
- SQLALCHEMY_ECHO 如果设置成 True,SQLAlchemy 将会记录所有 发到标准输出(stderr)的语句,这对调试很有帮助。
- 最后实例化Flas 对象和数据库对象,后面会使用到。
创建模型和数据库映射
# model
class ShortLink(db.Model):
__tablename__ = 'tb_short_link'
id = db.Column(db.Integer, primary_key=True)
short_key = db.Column(db.String(30), unique=True, nullable=False) # 短连接KEY,数据库唯一
source_url = db.Column(db.String(300), nullable=False) # 原连接
created_time = db.Column(db.DateTime, nullable=False)
- ShortLink 作为短连模型,指定和数据库映射的表名称为 tb_short_link。
- 更多可参考flask-sqlalchemy官方文档:www.pythondoc.com/flask-sqlal…
生成短连接口
@app.route("/short-link/create", methods=['POST', 'GET'])
def create_short_link():
"""创建短连接"""
SOURCE_KEYS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9']
url = request.args.get('url')
if not url or not re.match(r'^https?:/{2}\w.+$', url):
return {'success': False, 'message': '参数url不合法'}
short_key = ''.join(random.sample(SOURCE_KEYS, 8)) # 数据库建了唯一索引,若重复提醒用户重试
sl = ShortLink(short_key=short_key, source_url=url, created_time=datetime.now())
db.session.add(sl)
db.session.commit()
short_full_url = 'http://localhost:9091/' + short_key # 线上更换成短连接域名
return {"id": sl.id, "short_full_url": short_full_url,
'created_time': sl.created_time.strftime('%Y-%m-%d %H:%M:%S')}
- 生成原理目前很简陋,仅做参考,定义一个包含所有字母和数据的集合,每次创建短连接从集合中随机取8位作为KEY,再和原链接关联,存入到数据库,这里暂不考虑碰撞和性能。
- 值得注意的是目前的做法每个相同的URL每次都会生成不同的短连接,如果你需要保证原链接唯一,可以对原链接取md5值后存储,当收到新的短连接请求后可用于判断是否已存在,如果存在直接返回已存在的短连接即可。
- 更加高效的可用python提供的hash库等组件实现。
根据短连重定向到原链接
@app.route("/<string:short_key>", methods=['GET'])
def redirect_source_url(short_key):
"""传入短连后重定向到到原链接"""
sl = ShortLink.query.filter_by(short_key=short_key).first()
return redirect(sl.source_url) if sl else abort(404)
- 根据用户传入的短连key从数据库查到原地址,再使用flask提供的重定向函数redirect重定向到原地址。
启动应用
首先创建数据库表,有两种方式:
一种是根据Model自动生成表。
# 在python控制台下执行
>>> from flask_short_link import db
>>> db.create_all()
另一种:在数据库客户端执行如下SQL脚本。
CREATE TABLE `tb_short_link` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`short_key` varchar(30) NOT NULL,
`source_url` varchar(300) NOT NULL,
`created_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `short_key` (`short_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
再调用app的run方法启动应用,设置端口为9091, 开启debug方便观察输出信息。
if __name__ == '__main__':
app.run(port=9091, debug=True)
控制台有如下输出说明启动成功。
Connected to pydev debugger (build 211.7142.45)
* Serving Flask app 'flask_short_link' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:9091/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 771-475-169
测试
为百度首页生成一个短连接作为测试。
mac:~ $ x-tools request http://127.0.0.1:9091/short-link/create?url=http://www.baidu.com
# 输出如下信息
{
"created_time": "2022-01-25 16:56:48",
"id": 78,
"short_full_url": "http://localhost:9091/f6rimes5"
}
- short_full_url 为短连接地址,后面的字符串为短连接KEY。
打开浏览器访问 http://localhost:9091/f6rimes5,重定向到百度,搞定!
查看数据库,如下是我测试生成的数据。
完整flask_short_link.py文件
x-tools 工具也可以用 curl 代替,感兴趣的朋友可以点击下面链接获取更多信息!