Send metadata with file as a response in Sanic Server Python - python-3.x

I want to send an audio file, along with some other metadata text (like server details, etc.), as a response in the Sanic server using Python.
I know that we can send, responses in text, JSON, or as a file. But would like to know, is there any way we can send the file as well as some other datatype as a response in a single request?
I tried with response.json by sending the metadata, as well as audio data (converting bytes to string), but while converting to string, I feel, some of the metadata of the audio is lost.
Would like to know, is there any effective way to send files, as well as some other metadata using Sanic in a single request?
Thanks :)

I just tried to do a little hack... I send the metadata in the header and stream the file as usual (response.file()), so from the client side, I read the metadata from the header, and get the file as resp
example:
headers = {
'metadata': text,
}
return await response.file(audio_file, headers=headers)

Related

Send audio from Node backend to frontend

I have Node/Express server set up in which several thousand audio files are stored within the src folder. I currently have a route set up that sends JSON data in the response object. I wish to also send an mp3 audio file that can be parsed at the front end and be converted to an audio object. I cannot figure out how to encode the audio file such that it may be sent. I have looked into Blobs (these don't seem to be possible in Node) and converting the binary file into a string that may be sent as part of the response body.
Any ideas as to how this may be possible?
You can directly send the audio file with something like:
res.sendFile(__dirname, "/src/audioFile.mp3");
Or you could Base64 encode the audio file for your frontend to parse:
fs.readFile("./src/audioFile.mp3", function(err, result) {
res.send(result.toString("base64"));
});

In ExpressJS, get original filename of a file sent with Body Binary in Postman

My pdf file is being sent to my server as binary data with Postman as seen in the picture attached.
The content of the file is being parsed on my ExpressJS server with req.on((chunk) => ...) etc.
Everything is fine, except the fact that I try to obtain the original filename(highlighted in red - valid-compressed-compressed.pdf) on the server, but I can't find the value anywhere in the request object.
Any suggestions, please?
Short answer: you cant.
If you look closely at the headers being sent with the request, there are no headers containing the filename. Therefore there are no headers you can access in express to retrieve that information. The only headers you send are Content-Type and Content-Length that gives some information about what you're sending. Other than that there's just the binary request body.
If you want to post a file and the filename you need to look into multipart/form-data (Multer).

node.js - download files and content from DB to client

I want to send to the client in the same request files from the dir and some content from the DB.
DB query -
const derivatives = await Derivative.findAll();
Here is the res -
res.status(200).send({
data: derivatives.map((derivative) => ({
id: derivative.id,
date: derivative.date,
})),
});
Here is the download -
const fileName = derivatives.map((name) => name.wex);
res.status(200).download(__dirname, `/assets/${fileName}`);
How can I add that to my response?
HTTP lets you specify a "content disposition" to indicate whether a response should be treated as a download, but doesn't support sending downloads arbitrarily, it has to be a response to a request. You can't have part of a response be a download and part be not, for a single request.
So if you need a file to be downloaded, and some JSON used to display some UI, you need to handle that in the client somehow. Either:
The client sends a request, and server returns JSON containing a URL for the download as well as the other data you wanted to send, and then the client requests a download of the URL through JavaScript
The client sends two requests, one for the download and one for the other data; this may complicate things on the server if you need to associate the two requests (want to do a database lookup only once for instance), but is simplest on the client.
The client sends a request, and the server returns a response containing the JSON data and the file data, packed in some way (the file data could be inside the JSON but that would be inefficient), and it's unpacked on the client (using JavaScript) and the client then constructs a Blob URL to "download" (in this case the data is already downloaded, so this just entails saving a file)
There are any number of ways you might pack the file and JSON data together, which is what /u/Quentin was alluding to. Sending both as one response may be better for performance, but you probably don't need to.

nestjs set response ContentType as stream values

with springboot you can send a stream of value (like sever-sent-event) to user with resposne content-type (#Response(produce = APPLICATION_JSON_STREAM_VALUE) so how use this with nestjs ???
If i well understand your need, you can set the content type of the response to application/octet-stream. That will allow you to send a stream to the client like a file for example

Nodejs: downloading and transforming large data from mongodb

I use Node JS. (Sails JS framework, but that's less important).
Purpose
Download a CSV file that includes data transformed from MongoDB.
That's the scenario of the server on a response to a large data download request
Read data from MongoDB.
Transform the data format (to CSV).
Send the data to response. (Download).
So, the user is expected to download this large data to their browser.
I'm not sure what would be the best way to handle such request.
MongoDB has built-in support for streaming and Node.js clients can provide a readable stream for the cursor. All HTTP response objects also provide a way to stream the response body through a series of writes or you can pipe to a socket when using WebSockets. Most of the work will be offloaded to the MongoDB server and Node.js was developed for exactly these kinds of requirements.
If you're going to use HTTP on the client side, you can use fetch() and stream the response body into memory. Here is an excellent article that shows how to efficiently process a response for large a CSV file:
const res = await fetch('/big-data.csv')
const csvStream = response.body
.pipeThrough(new TextDecoder())
.pipeThrough(new CSVDecoder())
for (;;) {
const {row, done} = await csvStream.read()
if (done) break
drain(row)
}
Don't forget that both the server and client support encoded content, so make sure you compress the responses to further improve I/O.
It is always a good idea to post some code of what you have tried so far.
First, you would have to retrieve the data from MongoDB using something like mongoose or Waterline if you are using SailsJS
Secondly you can use a library like csv to convert the data to a csv file.
Once you have created the file you can return the file to the user using the sails response like so:
res.attachment('path/to/file.csv');

Resources