1

I've posted this before and deleted after being pointed to this post because I thought it may solve it. Several hours of headaches later I am none the wiser and cannot deduce a solution to my problem. But I am as mentioned often quite new to all this.

In my backend I have these two functions:

@app.get("/mdstats_team")
async def get_mdstats_team():
    '''
    get events summary df for the matchday
    :return: json of eventdf
    '''
    eventdf = get_eventdf(WEEK)
    eventdf = eventdf[eventdf.groupby('event_type')[0].transform(max) == eventdf[0]]
    eventdf.columns = ['Team', 'Statistic', 'Max']
    return json.loads(eventdf.to_json(orient='records'))

@app.get("/md_events_team/{event}")
async def md_events_team(event="shot"):
    '''
    returns the filtered eventdf per event
    :param event: string, event to be filtered
    :return: json with team, event, score per row
    '''
    df = get_eventdf(WEEK)
    df.columns = ['team', 'event', 'score']
    return json.loads(df[df.event == event.upper()].to_json(orient='records'))

From the other post I've tried awaiting the df from get_eventdf(). WEEK is a preloaded pandas dataframe. Awaiting, i.e: df = await get_eventdf(WEEK) results in the same error.

I've tried fetching it in multiple ways, like so:

async function getData(endpoint) 
{
    return fetch(endpoint)
        .then((d) => d.json());
}
$: summary = getData(summary_endpoint);
$: shot = getData(shot_endpoint);

It works sometimes, but most of the times I get this error:

D:\project\frontend\node_modules\undici\lib\fetch\index.js:199
        Object.assign(new TypeError('fetch failed'), { cause: response.error })
                      ^

TypeError: fetch failed
    at Object.processResponse (D:\project\frontend\node_modules\undici\lib\fetch\index.js:199:23)
    at D:\mondaystats\frontend\node_modules\undici\lib\fetch\index.js:928:38
    at node:internal/process/task_queues:141:7
    at AsyncResource.runInAsyncScope (node:async_hooks:202:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:138:8)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  cause: Error: connect ECONNREFUSED ::1:8000
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) {
    errno: -4078,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '::1',
    port: 8000
  }
}

Fetching just one of the endpoints works always, i.e:

$: summary = getData(summary_endpoint);
//$: shot = getData(shot_endpoint);

or

//$: summary = getData(summary_endpoint);
$: shot = getData(shot_endpoint);

I am perplexed because I have used the same backend with the same structure, serving jsons from pandas dataframes computed on the fly with about 40 endpoints in my first project (using React). I don't understand why this, with just 2 endpoints runs into trouble already.

Your help is much appreciated.

Chris
  • 18,724
  • 6
  • 46
  • 80
Olli
  • 906
  • 10
  • 25
  • Update @Chris I have dropped `async` now on all functions and unfortunately still get the exact same error. edit: Actually if I drop async, it seems that it won't even load one endpoint. Before it was just one or the other but not both – Olli Sep 04 '22 at 14:38
  • @Chris Thank you. I am sorry, I am not sure how to setup a minimal reproducible sample without asking volunteers here to go through a setup of fastapi and svelte, the svelte repls would only be frontend. 1. Yes, the response works fine for all parameters and both endpoints. 2. I think svelte's await does that, which I am using. 3. Yes it continues to run and I can still get the data via the browser. Thanks again! – Olli Sep 04 '22 at 14:46
  • @Chris thanks a lot I will check it out. I somehow think it might also be the parameterized endpoint. It's just so weird that I am doing nothing different from when I build my react app. Thanks again. I also switch to to_dict() as indicated in your other post – Olli Sep 04 '22 at 15:20
  • @Chris Thanks, Sure. This has worked, another thing that worked is to put them all in a Promise.all() (this worked with localhost too for some reason). Sorry I somehow did not get the earlier notification only this one. – Olli Sep 07 '22 at 10:17
  • @Chris I could sure, but I think the 127.0.0.1 is probably the best solution as also indicated in the github issue and I'll gladly accept your answer and will add the promise all as addition afterwards (maybe in the late afternoon CET). – Olli Sep 07 '22 at 10:43

1 Answers1

1

As described in this github issue, which is associated with the undici package that throws the TypeError: fetch failed, as shown in your error log, there seems to be an issue when connecting to localhost, which has to do with them switching the default ordering of DNS entries in node v17.

Until the issue gets resolved (see here), you might as well replace localhost with 127.0.0.1 in your HTTP requests to the API. For example, a fetch request to http://localhost:8000/mdstats_team should instead look like this:

http://127.0.0.1:8000/mdstats_team

On a side note, I would suggest you have a look at this answer on how to convert a DataFrame into JSON and return it from FastAPI backend, instead of the way you are currently using.

Chris
  • 18,724
  • 6
  • 46
  • 80
  • I have just spent hours troubleshooting a previously healthy build that has mysteriously starting failing with "TypeError: fetch failed". It seems to have the same cause and, in my case, downgrading to Node v16.19.0 allowed the build to succeed again. – Michael12345 Jan 07 '23 at 18:48