简体   繁体   English

将 reactjs 前端与 python + flask 后端相结合

[英]combining reactjs frontend with python + flask backend

I have a reactjs frontend that has a react-leaflet map.我有一个带有 react-leaflet 映射的 reactjs 前端。 On click of the map, I can access the latitude and longitude.单击地图,我可以访问纬度和经度。 On this same click, I need to get a Python script to load.在同一次点击中,我需要加载一个 Python 脚本。 I have a Flask endpoint as my backend server, and my react frontend can hit this endpoint, I'm just not sure how to tie everything together and have the Python script load and work properly:(我有一个 Flask 端点作为我的后端服务器,我的 React 前端可以访问这个端点,我只是不确定如何将所有内容连接在一起并让 Python 脚本加载并正常工作:(

my React code-我的 React 代码-

import { useMapEvents, Popup, Marker} from "react-leaflet";

const PopupInfo = () => {
    const [markers, setMarkers] = useState([]);

    const map = useMapEvents({
        async click(e) {
            const newMarker = e.latlng
            setMarkers([...markers, newMarker])
            console.log(e.latlng, "info")
            //access coordinates to load the python script
            const response = await fetch(`/coordinates?sel_lat=${e.latlng.lat}&sel_lon=${e.latlng.lng}`,
                {
                method: 'GET',
                headers: {
                Accept: 'application/json',
                }}); 
            console.log(response, 'TESTING PROMISE')  
            if (!response.ok) {
                throw new Error(`Error! status: ${response.status}`);
            }         
            const result = response.json();         
            console.log('result is: ', JSON.stringify(result, null, 4));  
    }
})
    return (
        <>
        {markers.map((marker, index) => 
            <Marker position={marker} key={index}>
                <Popup>Latitude: ({marker.lat})<br></br>Longitude: ({marker.lng})</Popup>
            </Marker>)}
        </>
    );
};

export default PopupInfo;

python code-蟒蛇代码-

import argparse
import time
import pandas as pd
import datetime as dt
import json

from src.bcolors import bcolors as bc
import src.config as cfg
import src.utils as utils
import src.cfsr as cfsr
import src.gfs as gfs

def parse_args():
    parser = argparse.ArgumentParser(
        description="PURPOSE: Extract current meteorological information\n \
                for a location and give climate context",
    )

    parser.add_argument(
        "--sel_lat", type=float, dest="sel_lat", help="Latitude of requested location"
    )
    parser.add_argument(
        "--sel_lon", type=float, dest="sel_lon", help="Longitude of requested location"
    )

    args = parser.parse_args()
##v2
    # print("optional arg is: " + args.sel_lat, args.sel_lon)
    return args


def main():

    start = time.time()
    args = parse_args()

    print(f"{bc.HEADER}EXTRACT INFO FOR SELECTED LOCATION{bc.ENDC}")
    print(f"{bc.HEADER}({args.sel_lat},{args.sel_lon}){bc.ENDC}")

    slat = args.sel_lat
    slon = args.sel_lon
    slon360 = utils.lon_to_360(args.sel_lon)
    if cfg.debug:
        fin_ij = utils.get_ij_data(cfg.file_ref, slat, slon360)
        print(
            f"{bc.BOLD}Selected grid point: {fin_ij.lat.values}, {fin_ij.lon.values}{bc.ENDC}"
        )

    if cfg.debug:
        fin_ij = utils.get_ij_data(cfg.file_ref, slat, slon360)
        print(
            f"{bc.BOLD}Selected grid point: {fin_ij.lat.values}, {fin_ij.lon.values}{bc.ENDC}"
        )

    print(f"Elapsed time initialization: {time.time()-start}s")
    this_time = time.time()

    sdoy = utils.calc_doy_noleap(cfg.today)

    print(f"Elapsed time doy: {time.time()-this_time}s")
    this_time = time.time()

    # Get data for location

    sdata_doy = cfsr.get_data_doy_loc(slat, slon360, sdoy)
    sdata_all = cfsr.get_data_loc(slat, slon360)

    print(f"Elapsed time load sdata: {time.time()-this_time}s")
    this_time = time.time()

    sqtiles = sdata_doy.sel(time=slice(f"{cfg.bsyear}", f"{cfg.beyear}")).quantile(
        cfg.qtiles
    )
    print(f"Elapsed time qtiles: {time.time()-this_time}s")
    this_time = time.time()

    fcvars = gfs.get_loc_fcvars(slat, slon360)

    print(f"Elapsed time fcvars: {time.time()-this_time}s")
    this_time = time.time()

    # Loading this year data

    sdata_y = cfsr.get_data_this_year_loc(slat, slon360)
    shmap_y = cfsr.get_hmap_this_year_loc(slat, slon360)
    shwcs_y = cfsr.get_hwcs_this_year_loc(slat, slon360)

    # Loading bounds (for max-min plots)
    sbounds = cfsr.get_bounds_loc(slat, slon360)

    print(f"Elapsed time load sdat_ty: {time.time()-this_time}s")
    this_time = time.time()
    doy_temp_ptile = (abs(sqtiles - fcvars)).idxmin(dim="quantile") * 100.0

    print(f"Elapsed time doy qtile: {time.time()-this_time}s")
    this_time = time.time()

    print(
        f"{bc.OKGREEN}Today's tmax {round(fcvars.tmax.values.item(),1)} at the selected point ({slat},{slon}) will be on the {int(doy_temp_ptile.tmax)}th percentile{bc.ENDC}"
    )
    print(
        f"{bc.OKGREEN}Today's tmin {round(fcvars.tmin.values.item(),1)} at the selected point ({slat},{slon}) will be on the {int(doy_temp_ptile.tmin)}th percentile{bc.ENDC}"
    )
    print(
        f"{bc.OKGREEN}Today's tmed {round(fcvars.tmed.values.item(),1)} at the selected point ({slat},{slon}) will be on the {int(doy_temp_ptile.tmed)}th percentile{bc.ENDC}"
    )

    #####################################################################
    #####################################################################
    sdata_doy.drop(["lat", "lon"]).to_dataframe().round(1).to_csv(
        f"{cfg.wrk_dir}/temp_doy.csv", index=False
    )
    sdata_y.drop(["lat", "lon"]).to_dataframe().round(1).to_csv(
        f"{cfg.wrk_dir}/temp_current_year.csv", index=True
    )
    shmap_y.drop(["lat", "lon"]).to_dataframe().round(1).to_csv(
        f"{cfg.wrk_dir}/hmap_current_year.csv", index=True
    )
    shwcs_y.drop(["lat", "lon"]).to_dataframe().round(1).to_csv(
        f"{cfg.wrk_dir}/hwcs_current_year.csv", index=True
    )
    sbounds_time = sbounds.assign_coords(
        doy=pd.date_range(
            dt.datetime(cfg.today.year, 1, 1),
            dt.datetime(cfg.today.year, 12, 31),
            freq="D",
        )
    )
    sbounds_time.drop(["lat", "lon"]).to_dataframe().round(1).to_csv(
        f"{cfg.wrk_dir}/bounds.csv", index=True
    )

    fcvars.to_dataframe().round(1).to_csv(f"{cfg.wrk_dir}/fcvars.csv", index=True)

    print(f"Elapsed time write csv files: {time.time()-this_time}s")
    this_time = time.time()

    print(f"{bc.HEADER}Writing out json file with loc info{bc.ENDC}")
    loc_stats = {
        "tmax": round(fcvars.tmax.values.item(), 1),
        "tmin": round(fcvars.tmin.values.item(), 1),
        "tmed": round(fcvars.tmed.values.item(), 1),
        "tmax_ptile": int(doy_temp_ptile.tmax),
        "tmin_ptile": int(doy_temp_ptile.tmin),
        "tmed_ptile": int(doy_temp_ptile.tmed),
        "tmax_alltime_record_x": sdata_all.tmax.max().values.item(),
        "tmax_alltime_record_n": sdata_all.tmax.min().values.item(),
        "tmin_alltime_record_x": sdata_all.tmin.max().values.item(),
        "tmin_alltime_record_n": sdata_all.tmin.min().values.item(),
        "tmed_alltime_record_x": sdata_all.tmed.max().values.item(),
        "tmed_alltime_record_n": sdata_all.tmed.min().values.item(),
    }

    with open(f"{cfg.wrk_dir}/loc_stats.json", "w", encoding="utf-8") as f:
        f.write(json.dumps(loc_stats, indent=2))

    print(f"Elapsed time write json file: {time.time()-this_time}s")
    this_time = time.time()

    print(f"{bc.OKGREEN}Elapsed time TOTAL: {time.time()-start}s{bc.ENDC}")


###############################################################################
# __main__  scope
###############################################################################

if __name__ == "__main__":

    raise SystemExit(main())

You should make python code to API then call api in React.您应该将 python 代码编写为 API,然后在 React 中调用 api。 Call api may be Post/Get/Patch.调用 api 可能是 Post/Get/Patch。 As for python api you can use Flask/Fast/Django or other framework.至于 python api,你可以使用 Flask/Fast/Django 或其他框架。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM