Skip to content

Commit 0ca5d65

Browse files
committed
[免费课] FastAPI 框架精讲
0 parents  commit 0ca5d65

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+46524
-0
lines changed

.gitignore

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
### Python template
2+
# Byte-compiled / optimized / DLL files
3+
__pycache__/
4+
*.py[cod]
5+
*$py.class
6+
7+
# C extensions
8+
*.so
9+
10+
# Distribution / packaging
11+
.Python
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*.cover
48+
.hypothesis/
49+
50+
# Translations
51+
*.mo
52+
*.pot
53+
54+
# Sphinx documentation
55+
docs/_build/
56+
57+
# PyBuilder
58+
target/
59+
60+
# pyenv
61+
.python-version
62+
63+
# celery beat schedule file
64+
celerybeat-schedule
65+
66+
# Environments
67+
.venv
68+
venv/
69+
ENV/
70+
.envs/*
71+
env.bak/
72+
venv.bak/
73+
74+
# Rope project settings
75+
.ropeproject
76+
77+
# mkdocs documentation
78+
/site
79+
80+
# godie
81+
.godie_cache/
82+
83+
# Logs
84+
/logs/
85+
*.log
86+
87+
# Runtime data
88+
pids
89+
*.pid
90+
*.seed
91+
*.pid.lock
92+
93+
# Directory for instrumented libs generated by jscoverage/JSCover
94+
lib-cov
95+
96+
# Coverage directory used by tools like istanbul
97+
coverage
98+
99+
# nyc test coverage
100+
.nyc_output
101+
102+
# Bower dependency directory (https://bower.io/)
103+
bower_components
104+
105+
# node-waf configuration
106+
.lock-wscript
107+
108+
# Compiled binary addons (http://nodejs.org/api/addons.html)
109+
build/Release
110+
111+
# Dependency directories
112+
node_modules/
113+
jspm_packages/
114+
115+
# Typescript v1 declaration files
116+
typings/
117+
118+
# Optional npm cache directory
119+
.npm
120+
121+
# Optional eslint cache
122+
.eslintcache
123+
124+
# Optional REPL history
125+
.node_repl_history
126+
127+
# Output of "npm pack"
128+
*.tgz
129+
130+
# Yarn Integrity file
131+
.yarn-integrity
132+
133+
134+
### Linux template
135+
*~
136+
137+
# temporary files which can be created if a process still has a handle open of a deleted file
138+
.fuse_hidden*
139+
140+
# KDE directory preferences
141+
.directory
142+
143+
# Linux trash folder which might appear on any partition or disk
144+
.Trash-*
145+
146+
# .nfs files are created when an open file is removed but is still being accessed
147+
.nfs*
148+
149+
150+
### Project template
151+
.pytest_cache/
152+
.ipython/
153+
154+
# Django stuff:
155+
godie/static/
156+
godie/staticfiles/
157+
godie/media/
158+
.static_storage/
159+
160+
# Flask stuff:
161+
instance/
162+
.webassets-cache
163+
164+
# Scrapy stuff:
165+
.scrapy
166+
167+
# Jupyter Notebook
168+
.ipynb_checkpoints
169+
170+
# SageMath parsed files
171+
*.sage.py
172+
173+
# Spyder project settings
174+
.spyderproject
175+
.spyproject
176+
177+
# pycharm
178+
/.idea/

README.md

Whitespace-only changes.

coronavirus/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/python3
2+
# -*- coding:utf-8 -*-
3+
# __author__ = '__Jack__'
4+
5+
from .main import application

coronavirus/database.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/python3
2+
# -*- coding:utf-8 -*-
3+
# __author__ = '__Jack__'
4+
5+
from sqlalchemy import create_engine, Column, String, Integer, BigInteger, Date, DateTime, ForeignKey, func
6+
from sqlalchemy.ext.declarative import declarative_base
7+
from sqlalchemy.orm import sessionmaker, relationship
8+
9+
SQLALCHEMY_DATABASE_URL = 'sqlite:///./coronavirus.db'
10+
# SQLALCHEMY_DATABASE_URL = "postgresql://username:password@host:port/database_name" # MySQL或PostgreSQL的连接方法
11+
12+
engine = create_engine(
13+
# echo=True表示引擎将用repr()函数记录所有语句及其参数列表到日志
14+
# 由于SQLAlchemy是多线程,指定check_same_thread=False来让建立的对象任意线程都可使用
15+
SQLALCHEMY_DATABASE_URL, encoding='utf-8', echo=True, connect_args={'check_same_thread': False}
16+
)
17+
18+
# 在SQLAlchemy中,CRUD都是通过会话(session)进行的,所以我们必须要先创建会话
19+
# flush()是指发送数据库语句到数据库,但数据库不一定执行写入磁盘;commit()是指提交事务,将变更保存到数据库文件
20+
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, expire_on_commit=True)
21+
22+
# 创建基本映射类
23+
Base = declarative_base(bind=engine, name='Base')
24+
25+
26+
class City(Base):
27+
__tablename__ = 'city'
28+
29+
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
30+
province = Column(String(100), unique=True, nullable=False, comment='省/直辖市')
31+
country = Column(String(100), nullable=False, comment='国家')
32+
country_code = Column(String(100), nullable=False, comment='国家代码')
33+
country_population = Column(BigInteger, nullable=False, comment='国家人口')
34+
data = relationship('Data', backref='city') # 'Data'是关联的类名;backref来指定反向访问的属性名称
35+
36+
created_at = Column(DateTime, server_default=func.now(), comment='创建时间')
37+
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment='更新时间')
38+
39+
__mapper_args__ = {"order_by": country_code} # 默认是正序,倒序加上.desc()方法
40+
41+
def __repr__(self):
42+
return f'{self.country}_{self.province}'
43+
44+
45+
class Data(Base):
46+
__tablename__ = 'data'
47+
48+
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
49+
city_id = Column(Integer, ForeignKey('city.id'), ondelete='CASCADE', comment='所属省/直辖市') # ForeignKey里的字符串格式不是类名.属性名,而是表名.字段名
50+
date = Column(Date, nullable=False, comment='数据日期')
51+
confirmed = Column(BigInteger, default=0, nullable=False, comment='确诊数量')
52+
deaths = Column(BigInteger, default=0, nullable=False, comment='死亡数量')
53+
recovered = Column(BigInteger, default=0, nullable=False, comment='痊愈数量')
54+
city = relationship('City', backref='data') # 'City'是关联的类名;backref来指定反向访问的属性名称
55+
56+
created_at = Column(DateTime, server_default=func.now(), comment='创建时间')
57+
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment='更新时间')
58+
59+
__mapper_args__ = {"order_by": confirmed}
60+
61+
def __repr__(self):
62+
return f'{repr(self.date)}:确诊{self.confirmed}例'
63+
64+
65+
""" 附上三个SQLAlchemy教程
66+
67+
SQLAlchemy的基本操作大全
68+
http://www.taodudu.cc/news/show-175725.html
69+
70+
Python3+SQLAlchemy+Sqlite3实现ORM教程
71+
https://www.cnblogs.com/jiangxiaobo/p/12350561.html
72+
73+
SQLAlchemy基础知识 Autoflush和Autocommit
74+
https://zhuanlan.zhihu.com/p/48994990
75+
"""

coronavirus/main.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/python3
2+
# -*- coding:utf-8 -*-
3+
# __author__ = '__Jack__'
4+
5+
from fastapi import Request, Depends, BackgroundTasks, APIRouter
6+
from pydantic import BaseModel
7+
from sqlalchemy.orm import Session
8+
9+
10+
# from coronavirus.database import engine, SessionLocal, Base
11+
12+
13+
from fastapi.staticfiles import StaticFiles
14+
from fastapi.templating import Jinja2Templates
15+
16+
17+
application = APIRouter()
18+
19+
20+
application.mount('/static', StaticFiles(directory='./coronavirus/static'), name='static')
21+
templates = Jinja2Templates(directory='./coronavirus/templates')
22+
23+
24+
# Base.metadata.create_all(bind=engine)
25+
26+
27+
@application.get("/")
28+
async def index(request: Request):
29+
return templates.TemplateResponse("index.html", {"request": request, "title": "This is title"}) # {"request": request}是必须的
30+
31+
32+
@application.get("/coronavirus")
33+
async def coronavirus():
34+
"""This is a simple tutorial"""
35+
return {"message": {"This is another route"}}
36+
37+
38+
# class StockRequest(BaseModel):
39+
# symbol: str
40+
#
41+
#
42+
# def get_db():
43+
# try:
44+
# db = SessionLocal()
45+
# yield db
46+
# finally:
47+
# db.close()
48+
#
49+
#
50+
# @application.get("/")
51+
# def home(request: Request, forward_pe=None, dividend_yield=None, ma50=None, ma200=None, db: Session = Depends(get_db)):
52+
# """
53+
# displays the stock screener dashboard / homepage
54+
# :return:
55+
# """
56+
# stocks = db.query(Stock)
57+
#
58+
# if forward_pe:
59+
# stocks = stocks.filter(Stock.forward_pe < forward_pe)
60+
#
61+
# if dividend_yield:
62+
# stocks = stocks.filter(Stock.dividend_yield > dividend_yield)
63+
#
64+
# if ma50:
65+
# stocks = stocks.filter(Stock.price > Stock.ma50)
66+
#
67+
# if ma200:
68+
# stocks = stocks.filter(Stock.price > Stock.ma200)
69+
#
70+
# return templates.TemplateResponse("home.html", {
71+
# "request": request,
72+
# "stocks": stocks
73+
# })
74+
#
75+
#
76+
# def fetch_stock_data(id_: int):
77+
# """
78+
# fetch data from yahoo finance
79+
# :param id_:
80+
# :return:
81+
# """
82+
# db = SessionLocal()
83+
# stock = db.query(Stock).filter(Stock.id == id_).first()
84+
#
85+
# yahoo_data = yf.Ticker(stock.symbol)
86+
#
87+
# stock.ma50 = yahoo_data.info["fiftyDayAverage"]
88+
# stock.ma200 = yahoo_data.info["twoHundredDayAverage"]
89+
# stock.price = yahoo_data.info["previousClose"]
90+
# stock.forward_pe = yahoo_data.info["forwardPE"]
91+
# stock.forward_eps = yahoo_data.info["forwardEps"]
92+
# if yahoo_data.info["dividendYield"]:
93+
# stock.dividend_yield = yahoo_data.info["dividendYield"] * 100
94+
#
95+
# db.add(stock)
96+
# db.commit()
97+
#
98+
#
99+
# @application.post("/stock")
100+
# async def create_stock(stock_request: StockRequest, background_tasks: BackgroundTasks, db: Session = Depends(get_db)):
101+
# """
102+
# created a stock and stores it in the database
103+
# :return:
104+
# """
105+
# stock = Stock()
106+
# stock.symbol = stock_request.symbol
107+
#
108+
# db.add(stock)
109+
# db.commit()
110+
#
111+
# background_tasks.add_task(fetch_stock_data, stock.id)
112+
#
113+
# return {
114+
# "code": "success",
115+
# "message": "stock created"
116+
# }

0 commit comments

Comments
 (0)