es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obteniendo FastAPI StreamedResponse a través de JS

Estoy tratando de obtener y console.logear los datos transmitidos desde FastApi a través de StreamedResponse usando fetch, pero no puedo hacer que funcione. Chrome indica “No se pueden leer las propiedades de null (leyendo ‘getReader’)” porque response.body es nulo. ¿Qué estoy haciendo mal?

Servidor

async def foo():
    for i in range(5):
        time.sleep(1)
        yield b'foobar'

@app.get('/bar')
async def bar():
    return StreamingResponse(foo(), media_type='text/plain')

Cliente

async function buttonclick() {
    let url = 'http://localhost:8000/bar';

    let options = {
        mode: 'no-cors',
        method: 'GET'
    }

    fetch(url, options)
        .then(processChunkedResponse)
        .then(onChunkedResponseComplete)
        .catch(onChunkedResponseError);
}

function onChunkedResponseComplete(result) {
    console.log('¡Todo listo!', result)
}

function onChunkedResponseError(err) {
    console.error(err)
}

function processChunkedResponse(response) {
    var text = '';
    var reader = response.body.getReader()
    var decoder = new TextDecoder();

    return readChunk();

    function readChunk() {
        return reader.read().then(appendChunks);
    }

    function appendChunks(result) {
        var chunk = decoder.decode(result.value || new Uint8Array, {stream: !result.done});
        console.log('Se obtuvo un fragmento de', chunk.length, 'bytes')
        text += chunk;
        console.log('El texto hasta el momento es de', text.length, 'bytes\n');
        if (result.done) {
            console.log('retornando')
            return text;
        } else {
            console.log('recurriendo')
            return readChunk();
        }
    }
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema está con la opción mode: 'no-cors'. Al establecer el modo en no-cors, response.body es nulo porque el navegador no permite el acceso al cuerpo de la respuesta en este modo. Puede eliminar esta opción para resolver el problema.

    Alternativamente, puede configurar el modo en cors y agregar los encabezados CORS apropiados en el lado del servidor para permitir solicitudes de origen cruzado.

    Aquí hay un código de cliente actualizado sin la opción mode: 'no-cors':

    “`async function buttonclick() {
    let url = ‘http://localhost:8000/bar’;

        let options = {
            method: 'GET'
        }
    
        fetch(url, options)
            .then(processChunkedResponse)
            .then(onChunkedResponseComplete)
            .catch(onChunkedResponseError);
    
    }
    
    
    function onChunkedResponseComplete(result) {
        console.log('¡todo hecho!', result)
    }
    
    function onChunkedResponseError(err) {
        console.error(err)
    }
    
    function processChunkedResponse(response) {
        var text = '';
        var reader = response.body.getReader()
        var decoder = new TextDecoder();
    
        return readChunk();
    
        function readChunk() {
            return reader.read().then(appendChunks);
        }
    
        function appendChunks(result) {
            var chunk = decoder.decode(result.value || new Uint8Array, {stream: !result.done});
            console.log('obtuve un fragmento de', chunk.length, 'bytes')
            text += chunk;
            console.log('texto hasta ahora es', text.length, 'bytes\n');
            if (result.done) {
                console.log('regresando')
                return text;
            } else {
                console.log('recurriendo')
                return readChunk();
            }
        }
    }```
    

Comments are closed.