将 Highcharts 与 FastAPI 结合使用
Using Highcharts with FastAPI
我从 FastAPI 开始,是 Highcharts 的新手。我的目标是使用 FastAPI 而不是 Flask 创建一个简单的 Highcharts 图。
在我的 app.py
我有,
import uvicorn
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from fastapi.templating import Jinja2Templates
from os.path import join, realpath, dirname
app = FastAPI()
dir_path = dirname(realpath(__file__))
app.mount("/static", StaticFiles(directory=join(dir_path, "static")), name="static")
templates = Jinja2Templates(directory=join(dir_path, "templates"))
origins = [
"http://localhost:3000",
"localhost:3000"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
@app.get("/graph")
def index(request, chartID='chart_ID', chart_type='line', chart_height = 500):
chart = {"renderTo": chartID, "type": chart_type, "height": chart_height, }
series = [{"name": 'Label1', "data": [1, 2, 3]}, {"name": 'Label2', "data": [4, 5, 6]}]
title = {"text": 'My Title'}
xAxis = {"categories": ['xAxis Data1', 'xAxis Data2', 'xAxis Data3']}
yAxis = {"title": {"text": 'yAxis Label'}}
render_dict = dict(request=request, chartID=chartID, chart=chart, series=series,
title=title, xAxis=xAxis, yAxis=yAxis)
return templates.TemplateResponse("index.html", render_dict)
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)
在 static
文件夹中我有 main.js
和 main.css
脚本,在 templates
文件夹中是我的 index.html
文件。但是当我 运行 它时,我得到 422 Unprocessable Entity
错误。
$(document).ready(function() {
$(chartID).highcharts({
chart: chart,
title: title,
xAxis: xAxis,
yAxis: yAxis,
series: series
});
});
* {
margin: 20px;
padding: 100px;
}
header {
background-color:rgba(33, 33, 33, 0.9);
color:#ffffff;
display:block;
font: 14px/1.3 Arial,sans-serif;
height:50px;
position:relative;
}
header h2{
font-size: 22px;
margin: 0px auto;
padding: 10px 0;
width: 80%;
text-align: center;
}
header a, a:visited {
text-decoration:none;
color:#fcfcfc;
}
.actions, .chart {
margin: 15px auto;
width: 34px;
}
button {
background: none repeat scroll 0 0 #E3E3E3;
border: 1px solid #BBBBBB;
border-radius: 3px 3px 3px 3px;
box-shadow: 0 0 1px 1px #F6F6F6 inset;
color: #333333;
font-size: 12px;
margin: 0 5px;
padding: 8px 0 9px;
text-align: center;
text-shadow: 0 1px 0 #FFFFFF;
width: 150px;
}
button:hover {
background: none repeat scroll 0 0 #D9D9D9;
box-shadow: 0 0 1px 1px #EAEAEA inset;
color: #222222;
cursor: pointer;
}
button:active {
background: none repeat scroll 0 0 #D0D0D0;
box-shadow: 0 0 1px 1px #E3E3E3 inset;
color: #000000;
}
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
<head>
</head>
<body class = "body">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<body>
<h3>{{ title }}</h3>
{% for p in paragraph %}
<p>{{ p }}</p>
{% endfor %}
{% if pageType == 'about' %}
<p>Contact box thing is here</p>
{% else %}
<p>not about page</p>
{% endif %}
<div id={{ chartID|safe }} class="chart" style="height: 100px; width: 500px"></div>
<script>
var chart_id = {{ chartID|safe }}
var series = {{ series|safe }}
var title = {{ title|safe }}
var xAxis = {{ xAxis|safe }}
var yAxis = {{ yAxis|safe }}
var chart = {{ chart|safe }}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="../static/main.js"></script>
</body>
</body>
</html>
错误 422 Unprocessable Entity
是由于提供给端点的数据格式不正确。
您应该在端点中定义 request
对象的类型
from fastapi import Request
# more code
@app.get("/graph")
def index(request: Request, chartID='chart_ID', chart_type='line', chart_height = 500):
这样,fastapi
就会知道第一个变量不会由用户提供(即谁 GET
提出了请求),而是由 [=13= 填充].
我从 FastAPI 开始,是 Highcharts 的新手。我的目标是使用 FastAPI 而不是 Flask 创建一个简单的 Highcharts 图。
在我的 app.py
我有,
import uvicorn
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from fastapi.templating import Jinja2Templates
from os.path import join, realpath, dirname
app = FastAPI()
dir_path = dirname(realpath(__file__))
app.mount("/static", StaticFiles(directory=join(dir_path, "static")), name="static")
templates = Jinja2Templates(directory=join(dir_path, "templates"))
origins = [
"http://localhost:3000",
"localhost:3000"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
@app.get("/graph")
def index(request, chartID='chart_ID', chart_type='line', chart_height = 500):
chart = {"renderTo": chartID, "type": chart_type, "height": chart_height, }
series = [{"name": 'Label1', "data": [1, 2, 3]}, {"name": 'Label2', "data": [4, 5, 6]}]
title = {"text": 'My Title'}
xAxis = {"categories": ['xAxis Data1', 'xAxis Data2', 'xAxis Data3']}
yAxis = {"title": {"text": 'yAxis Label'}}
render_dict = dict(request=request, chartID=chartID, chart=chart, series=series,
title=title, xAxis=xAxis, yAxis=yAxis)
return templates.TemplateResponse("index.html", render_dict)
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)
在 static
文件夹中我有 main.js
和 main.css
脚本,在 templates
文件夹中是我的 index.html
文件。但是当我 运行 它时,我得到 422 Unprocessable Entity
错误。
$(document).ready(function() {
$(chartID).highcharts({
chart: chart,
title: title,
xAxis: xAxis,
yAxis: yAxis,
series: series
});
});
* {
margin: 20px;
padding: 100px;
}
header {
background-color:rgba(33, 33, 33, 0.9);
color:#ffffff;
display:block;
font: 14px/1.3 Arial,sans-serif;
height:50px;
position:relative;
}
header h2{
font-size: 22px;
margin: 0px auto;
padding: 10px 0;
width: 80%;
text-align: center;
}
header a, a:visited {
text-decoration:none;
color:#fcfcfc;
}
.actions, .chart {
margin: 15px auto;
width: 34px;
}
button {
background: none repeat scroll 0 0 #E3E3E3;
border: 1px solid #BBBBBB;
border-radius: 3px 3px 3px 3px;
box-shadow: 0 0 1px 1px #F6F6F6 inset;
color: #333333;
font-size: 12px;
margin: 0 5px;
padding: 8px 0 9px;
text-align: center;
text-shadow: 0 1px 0 #FFFFFF;
width: 150px;
}
button:hover {
background: none repeat scroll 0 0 #D9D9D9;
box-shadow: 0 0 1px 1px #EAEAEA inset;
color: #222222;
cursor: pointer;
}
button:active {
background: none repeat scroll 0 0 #D0D0D0;
box-shadow: 0 0 1px 1px #E3E3E3 inset;
color: #000000;
}
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
<head>
</head>
<body class = "body">
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<body>
<h3>{{ title }}</h3>
{% for p in paragraph %}
<p>{{ p }}</p>
{% endfor %}
{% if pageType == 'about' %}
<p>Contact box thing is here</p>
{% else %}
<p>not about page</p>
{% endif %}
<div id={{ chartID|safe }} class="chart" style="height: 100px; width: 500px"></div>
<script>
var chart_id = {{ chartID|safe }}
var series = {{ series|safe }}
var title = {{ title|safe }}
var xAxis = {{ xAxis|safe }}
var yAxis = {{ yAxis|safe }}
var chart = {{ chart|safe }}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="../static/main.js"></script>
</body>
</body>
</html>
错误 422 Unprocessable Entity
是由于提供给端点的数据格式不正确。
您应该在端点中定义 request
对象的类型
from fastapi import Request
# more code
@app.get("/graph")
def index(request: Request, chartID='chart_ID', chart_type='line', chart_height = 500):
这样,fastapi
就会知道第一个变量不会由用户提供(即谁 GET
提出了请求),而是由 [=13= 填充].