are you referring to media ( Image ) link download via Power BI , if yes , can you please connect me to exact part of this update as i am not able to find this.
Dear Josh, I understand that a new release was planned which will allow to download and show images in PowerBI without making all the data public. Is it foreseeable by now when this new release will be published?
You mean this article is not just about an alternative way to âimportâ the kobotoolbox data into PowerBi (we currently do it with json), but this alternative way (other than with the json-method) allows to show images in PowerBi?
EDIT:
Looks like the answer is: no. So, is the only option to download the images to a public server and take it from there to at least keep the rest of the data private? Or is there a new release coming which adresses the issue?
Hi @york_rff, the article describes a method connecting your data on Kobo to Power BI, etc. in the same format that you can download the data asynchronously and manually import. These exports will include URLs to your submission media files. From there it is up to the client on how they are able to pull images from those URLs to display. If the client is unable to make authenticated requests do this, then youâll have to make your data public or, as you suggest, move the images to another location that doesnât require authentication.
Dear Josh, thanks for the further input, though I am still not fully sure whether you are saying that without making the data public there is simply no way to dynamically (API etc.) load the image files themselves directly to PowerBI or indirectly via a private server (but that manual workarounds like âDownthemallâ need to be applied) and that there are no plans to make this possible. Ist that the case?
I would already be fine, if the public/private choice was possible separately for image type data (so that images can be put on public while the rest of the data will remain private). Anything like that in the making?
Dear all, any experiences / best practices around Jannaâs idea to first transfer the image files to another server and then let PowerBI query them from there?
Instead of a server where I eventually have the same public/private status issue, I tend to believe that it needs to be a Microsoft cloud product (Sharepoint?), so that it might be able to become part of PowerBIâs authentification system?
Any input (including failed attempts) appreciated!
Dear all who are interested in a simple way to make (a very big number of) photos from kobo questionnaires dynamically available in PowerBI. What is your simplest solution, you have found?
By the way: âSimpleâ doesnât mean to lose the link to the form id (otherwise it is not possible to filter the photos / relate them to the right context).
EDIT (as not third âReplyâ is allowed to this obviously neglected thread):
For who ever is struggling to get images smoothly into PowerBI, here is how we are trying it with some success at the moment:
Load the field â_attachmentsâ from your kobo form:
Expand the records to get the details, including correct UUID:
Save the images as 30k packages per cell (to put them together again in the report, using DAX formulas). A lot of requirements are defined by the design of the rest of the modelling, but maybe the following can stimulate thoughts, if you are looking for similar solutions.
let
Source = GetKoboData(ââŚâ),
#âRecordDetails Renameâ = Table.RenameColumns(Source, {{âColumn1â, âRecordDetailsâ}}),
#âExpanded UnlimitedWithFormulaâ = Table.ExpandRecordColumn(#âRecordDetails Renameâ,âRecordDetailsâ,
Table.ToList(Table.SelectColumns(Record.ToTable(Record.Combine(List.Select(Table.Column(#âRecordDetails Renameâ,âRecordDetailsâ), each _ <> ââ and _ <> null))), âNameâ)),
Table.ToList(Table.SelectColumns(Record.ToTable(Record.Combine(List.Select(Table.Column(#âRecordDetails Renameâ,âRecordDetailsâ), each _ <> ââ and _ <> null))), âNameâ))
),
#âRemoved Other Columnsâ = Table.SelectColumns(#âExpanded UnlimitedWithFormulaâ,{â_idâ, â_attachmentsâ, âsitevisit_form/inst_centre/centre_photo1â, âsitevisit_form/inst_centre/centre_photo2â}),
#âExpanded _attachmentsâ = Table.ExpandListColumn(#âRemoved Other Columnsâ, â_attachmentsâ),
#âExpanded _attachments1â = Table.ExpandRecordColumn(#âExpanded _attachmentsâ, "attachments", {âdownload_urlâ, âfilenameâ}, {âdownload_urlâ, âfilenameâ}),
#âSplit Column by Delimiterâ = Table.SplitColumn(#"Expanded attachments1", âfilenameâ, Splitter.SplitTextByEachDelimiter({â/â}, QuoteStyle.Csv, true), {âfilename.1â, âfilenameâ}),
#âFiltered Rowsâ = Table.SelectRows(#âSplit Column by Delimiterâ, each [filename] <> null and [filename] <> ââ),
#âRemoved Columns1â = Table.RemoveColumns(#âFiltered Rowsâ,{âfilename.1â}),
#âUnpivoted Other Columnsâ = Table.UnpivotOtherColumns(#âRemoved Columns1â, {"id", âdownload_urlâ, âfilenameâ}, âAttributeâ, âValueâ),
#âAdded Conditional Columnâ = Table.AddColumn(#âUnpivoted Other Columnsâ, âKeepRowâ, each if [filename] = [Value] then true else false, Logical.Type),
#âFiltered Rows1â = Table.SelectRows(#âAdded Conditional Columnâ, each ([KeepRow] = true)),
#âRemoved Columnsâ = Table.RemoveColumns(#âFiltered Rows1â,{âKeepRowâ}),
#âDuplicated Columnâ = Table.DuplicateColumn(#âRemoved Columnsâ, âdownload_urlâ, âdownload_url2â),
// Relative Path in next step needed. Otherwise, dynamic source error appears
#âSplit column by delimiter 1â = Table.SplitColumn(#âDuplicated Columnâ, âdownload_url2â, Splitter.SplitTextByEachDelimiter({KoboLogin}, QuoteStyle.Csv), {âImageURL.1â, âImageURLâ}),
#âGet Contentâ = Table.AddColumn(#âSplit column by delimiter 1â, âContentâ, each Web.Contents(KoboImageURL,
[RelativePath=â/media/â & SelectedPhotoSize{0} & â?media_file=â & KoboLogin & [ImageURL],
ManualStatusHandling={404}])),
Filesize = Table.AddColumn(#âGet Contentâ, âFilesizeâ, each Binary.Length([Content]), Int64.Type),
#âFiltered Filesizeâ = Table.SelectRows(Filesize, each [Filesize] > 1000),
#âRenamed Columnsâ = Table.RenameColumns(#âFiltered Filesizeâ,{{âValueâ, âNameâ}}),
#âRemoved Other Columns1â = Table.SelectColumns(#âRenamed Columnsâ,{âContentâ, âNameâ, âdownload_urlâ, âAttributeâ, âFilesizeâ}),
//Creates Splitter function
SplitTextFunction = Splitter.SplitTextByRepeatedLengths(30000),
//Converts table of files to list
ListInput = Table.ToRows(#âRemoved Other Columns1â),
//Function to convert binary of photo to multiple
//text values
ConvertOneFile = (InputRow as list) =>
let
BinaryIn = InputRow{0},
FileName = InputRow{1},
Field2 = InputRow{2},
Field3 = InputRow{3},
BinaryText = Binary.ToText(BinaryIn, BinaryEncoding.Base64),
SplitUpText = SplitTextFunction(BinaryText),
AddFileName = List.Transform(SplitUpText, each {FileName,Field2,Field3,})
in
AddFileName,
//Loops over all photos and calls the above function
ConvertAllFiles = List.Transform(ListInput, each ConvertOneFile()),
//Combines lists together
CombineLists = List.Combine(ConvertAllFiles),
//Converts results to table
ToTable = #table(type table[Name=text,URL=text,KoboField=text,Pic=text],CombineLists),
//Adds index column to output table
AddIndexColumn = Table.AddIndexColumn(ToTable, âIndexâ, 0, 1),
#âAdded customâ = Table.AddColumn(AddIndexColumn, âphoto_dateâ, each #datetimezone(1970,1,1,0,0,0,0,0) + #duration(0,0,0,Number.From(Text.Start([Name],10)))),
#âChanged column typeâ = Table.TransformColumnTypes(#âAdded customâ, {{âphoto_dateâ, type datetimezone}}),
#âCalculated dateâ = Table.TransformColumns(#âChanged column typeâ, {{âphoto_dateâ, each DateTime.Date(), type nullable date}}),
#âReplaced errorsâ = Table.ReplaceErrorValues(#âCalculated dateâ, {{âphoto_dateâ, #date(1970, 1, 1)}})
in
#âReplaced errorsâ