基本上,我正在开发一个API,它接收POST方法,然后使用一些数据创建一个json并发送它。
有一些约束,例如,我在数据库中的名称与json中需要的名称不同,但值必须相同。因此,我所做的就是创建一个字典,并将数据库中的名称与json中的名称关联起来。
代码说明:
我收到一个post方法,其中包含一条body消息,该消息对于验证数据库中是否存在该值非常有用。如果存在,我将执行另一个查询,该查询将检索属于我在正文中接收的值的所有设备。然后,我使用influxDB执行另一个查询,以获取db中的所有值。
在第一部分中,我所做的是对我所拥有的每一个设备检查ID是否存在于influxDB中,如果存在,则存储值。
在存储了该值之后,我检查我的设备名是否有一个通讯器(我在数据库中没有这个名称),并且对之前收到的值进行舍入,并将其附加到响应中。
在第二部分中,我只检查响应中有哪些名称,然后将字典中的值放在字典中,而不是在响应中,值为0(因为这些名称/值在数据库中没有,但在json响应中是必需的)。
代码:
json_data = {
"wid":None,
"time_loc":None,
"date_loc":None,
"time_utc":None,
"temp_out": "outTemp",
"temp_in": "inTemp",
"hum_out": "outHumidity",
"hum_in": "inHumidity",
"barometer": "barometer",
"altimeter": "altimeter",
"raw_bar":None,
"bar_trend":None,
"wind_spd": "windSpeed",
"wind_dir": "windDir",
"wind_avg_2min":None,
"wind_avg_10min":None,
"wind_gust_10min":None,
"wind_gust_dir": "windGustDir",
"dew_point": "dewpoint",
"dew_point_cal":None,
"wind_chill": "windchill",
"heat_index": "heatindex",
"thsw_index":None,
"uv": "UV",
"solar_radiation":None,
"rain_rate": "rainRate",
"storm_rain":None,
"rain_15min":None,
"rain_1h":None,
"rain_day":None,
"rain_daily":None,
"rain_24":None,
"rain_month":None,
"rain_year":None,
"et_day": "ET" ,
"et_month":None,
"et_year":None,
"temp_extra_0": "extraTemp1",
"temp_extra_1": "extraTemp2",
"temp_extra_2": "extraTemp3",
"temp_extra_3": "extraTemp4",
"temp_extra_4": "extraTemp5",
"temp_extra_5": "extraTemp6",
"temp_extra_6": None,
"temp_leaf_0":"leafTemp1",
"temp_leaf_1": "leafTemp2",
"temp_leaf_2": None,
"temp_leaf_3":None,
"temp_soil_0": "soilTemp1",
"temp_soil_1": "soilTemp2",
"temp_soil_2": "soilTemp3",
"temp_soil_3": "soilTemp4",
"hum_extra_0": "extraHumid1",
"hum_extra_1": "extraHumid2",
"hum_extra_2": "extraHumid3",
"hum_extra_3": "extraHumid4",
"hum_extra_4": "extraHumid5",
"hum_extra_5": "extraHumid6",
"hum_extra_6": "extraHumid7",
"soil_moist_0": "soilMoist1",
"soil_moist_1": "soilMoist2",
"soil_moist_2": "soilMoist3",
"soil_moist_3": "soilMoist4",
"wet_leaf_0": "leafWet1",
"wet_leaf_1": "leafWet2",
"wet_leaf_2":None,
"wet_leaf_3":None,
"console_batt":None,
"stations_batt_status":None,
"forecast_icon":None,
"forecast_rule":None,
"sunrise_loc_time":None,
"sunset_loc_time":None,
}
@app.route("/info/", methods=["POST", "GET"])
def get_current_data_devices():
isAuth = False
auth = request.authorization
if auth and auth.username == ApiFlask.post_auth["username"] and auth.password == ApiFlask.post_auth["password"]:
isAuth = True
else:
isAuth = False
return "Unauthorized", 401
if isAuth:
data = request.get_data(as_text=True)
data = json.loads(data)
g_id = data["gateway_id"]
print(f"gateway_id: {g_id}")
valid_gateway = ApiFlask.getValidGateway(g_id)
if(valid_gateway):
devices = ApiFlask.getDataFromDevices(g_id)
influx_results = influxDB.get_all_devices()
response = []
# FIRST PART
for device in devices:
influx_value = 0
for key in influx_results:
#print(key)
if str(device["d_id"]) == str(key):
influx_value = influx_results[key]
print(influx_results[key])
break
for key, val in ApiFlask.json_data.items():
if str(device["d_piv_slug"]) == str(val):
try:
aux_value = round(influx_value, 2)
#print(influx_value)
except:
aux_value = 0
if str(device["d_piv_slug"]) == None:
break
response.append({key: aux_value})
break
# SECOND PART
not_in_database = []
for key in ApiFlask.json_data:
if key not in [list(item.keys())[0] for item in response]:
not_in_database.append({key:0})
for item in not_in_database:
for key in item:
if response: # se a lista tiver conteudo, tem keys
if key not in response[0].keys():
response.append({key:item[key]})
else:
response.append({key:item[key]})
response.sort(key=lambda x: list(ApiFlask.json_data).index(list(x.keys())[0]))
return json.dumps(response, indent=4), 200
else:
return 'Bad Request' , 400我想知道这个代码是不是好的,如果不是很实用的话.
发布于 2023-05-21 04:43:34
json_data = {
"wid": ...数据结构很好。但是标识符的名字实在是太糟糕了,它告诉我的很少。将其称为db_to_json_name (如果我已经正确地阅读了代码,但仍然不确定)。
def get_current_data_devices():
isAuth = False佩普-8要求你拼写它,is_auth。考虑更详细:is_authorized。然后,没有混淆的概念,“是认证的”。
这个函数,嗯,有点长。我并不是说时间太长了。但它快到了。留心你可以从中提取的帮手。
if isAuth:考虑早点救人
if not isAuth:
return 'Bad Request' , 400其优点是功能体的其余部分将位于离左侧边缘更近的四个空格。
print(f"gateway_id: {g_id}") 考虑在这里使用记录器。如果没有其他的话,你可以免费得到时间戳。
if(valid_gateway):失去无关的( ) parens --这不是C代码。
再一次,你可以提前保释(if not valid_gateway:)。这将拯救另一个缩进水平。或者,您可以将剩余部分提取为助手函数,该函数将再次重置缩进级别,并为您的测试套件公开测试候选。
# FIRST PART
...
# SECOND PART 天哪,你要杀了我!如果“第一”/“第二”是对外部文档的引用,则将文档与CodeReview提交一起包括在内。否则,我就会问,“你想告诉我什么?”
我典型的建议是释放出一对助手函数。但是通常我们有一个类似于# reticulate the splines的注释,所以我们知道助手应该被命名为def reticulate_splines():。在这里,我完全不知所措,你没有给绅士读者提供任何提示。
except:
aux_value = 0 不是的。
你好像在和round(None)打交道。不要使用裸的except,以免干扰KeyboardInterrupt的CTRL/C处理。
更喜欢except TypeError:,如果这是你的意图的话。或者说只抓住了except Exception:,因为flake8无疑是想告诉你当你晕倒的时候。
就在“第一部分”中,你似乎可以明智地提取出一对小帮手。命名它们将提供一些文档价值。
在“第二部分”中,您可能会发现集差比循环更方便。
考虑将not_in_database重命名为missing_from_database。为什么?人类在标识符中做得更好,这些标识符是用积极的而不是消极的表示的。这样来解释代码的行为就更容易了。
if response:
if key not in response[0].keys():
response.append({key:item[key]})
else:
response.append({key:item[key]})这里有一对测试和一对赋值,这看起来像更多代码,而不是必要的。测试“这个和那个”能给我们只分配一个任务的代码吗?
response.sort(key=lambda x: list(ApiFlask.json_data).index(list(x.keys())[0]))对于匿名的一行来说,这是太多的代码了。请把它命名为def函数。
最重要的是,你告诉我有一对网络动词对这个函数有效:methods=["POST", "GET"]
我还在等笑话呢。这些动词的行为不同吗?我们是否有任何自动的单元测试来验证这个函数的行为,或者它的助手的行为?我没注意到有什么是特定的。
各种DB函数似乎读取/获取数据。如果它们对表有副作用,一定要调用它,并考虑选择一个函数名来澄清这一点。
此代码实现了它的一些设计目标。
在此提交文件中可能缺少一些评审上下文。如前所述,如果没有额外的上下文,我将不愿意将维护任务委托给这个代码库,并且不愿意接受这些任务,因为在添加新功能之前,需要偿还一些技术债务。在将代码合并到main之前,有机会对其进行改进。
发布于 2023-05-24 17:38:51
关于身份验证:我希望看到在您的路由之外实现的逻辑,方法是使用装饰器来保护需要身份验证的视图(路由)。
由于您使用的是Api烧瓶,那么根据他们的文档,您需要如下所示:
@app.auth_required(auth)并根据需要添加一些身份验证代码。
您目前只有一条路径这一事实并没有改变这样的事实:您的函数应该只做一件事,并且做得很好。您的方法很容易出错,因为您在多个地方设置isAuth变量。
要重申以前说过的话,不要吞咽例外。尤其是当你抓住他们所有人的时候。相反,要具体说明你期望发生什么样的异常。使用记录器,并记录它们。这将有助于稍后进行调试。如果您只想让aux_value的回退值为0,那么看起来违约是合适的。
https://codereview.stackexchange.com/questions/285073
复制相似问题