I would download file on local the create a stream then send to an API.
In localhost files get created via blobClient.downloadToFile(defaultFile);
But When I deploy function it can not find file to stream, so I think that the download does not happen or in bad location.
I get this error
[Error: ENOENT: no such file or directory, open 'D:homesitewwwrootimportPbixexampleName.pbix'
Here’s my code
const blobServiceClient = BlobServiceClient.fromConnectionString( process.env.CONNEXION_STRING ); const containerClient = blobServiceClient.getContainerClient( params.containerName ); const blobClient = containerClient.getBlobClient(process.env.FILE_LOCATION); // get file from storage let blobData; var defaultFile = path.join(params.baseDir, `${params.reportName}.pbix`); // use path module let stream; try { blobData = await blobClient.downloadToFile(defaultFile); console.log(blobData); stream = fs.createReadStream(defaultFile); } catch (error) { params.context.log(error); console.log(error); } var options = { method: "POST", url: `https://api.powerbi.com/v1.0/myorg/groups/${params.groupId}/imports?datasetDisplayName=${params.reportName}`, headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${params.accessToken} `, }, formData: { "": { value: stream, options: { filename: `${params.reportName}.pbix`, contentType: null, }, }, }, }; //check if file keep in mem return new Promise(function (resolve, reject) { request(options, function (error, response) { if (error) { params.context.log(error); reject(error); } else { params.context.log(response); resolve(response.body); } fs.unlinkSync(defaultFile); }); });
I found this post having same issue , that’s why I user path
module and passed __dirname to function params.baseDir
.
Advertisement
Answer
If you want to download a file from Azure blob and read it as a stream, just try the code below, in this demo, I try to download a .txt file to a temp folder(you should create it first on Azure function)and print its content from the stream for a quick test:
module.exports = async function (context, req) { const { BlockBlobClient } = require("@azure/storage-blob") const fs = require('fs') const connStr = '<connection string>' const container = 'files' const blobName = 'test.txt' const tempPath = 'd:/home/temp/' const tempFilePath = tempPath + blobName const blobClient = new BlockBlobClient(connStr,container,blobName); await blobClient.downloadToFile(tempFilePath).then(async function(){ context.log("download successfully") let stream = fs.createReadStream(tempFilePath) //Print text content,just check if stream has been readed successfully context.log("text file content:") context.log(await streamToString(stream)) //You can call your API here... }) function streamToString (stream) { const chunks = []; return new Promise((resolve, reject) => { stream.on('data', (chunk) => chunks.push(Buffer.from(chunk))); stream.on('error', (err) => reject(err)); stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); }) } context.res = { body: 'done' } }
Result
File has been downloaded:
read as stream successfully: