Tuesday, March 29, 2022

Tableau, TabPy, and the Case of No Input Rows

 I haven't scientifically confirmed this or anything, but it sure seems like if you pass an empty dataframe to a TabPy script, then no matter how many rows you may return from the script, Tableau Prep Builder will insist that you in fact returned no rows. This is annoying because you can run the same script from a command line and get output.

The fix is that you have to supply at least one row to the script, and then just ignore it entirely. This will placate Tableau Prep Builder and allow execution to continue.

Thursday, February 3, 2022

Tableau Prep Builder: "Why do I have X rows when I export to a .hyper and X*2 rows when I export to Excel? Wait, now it's X*3?"

 Tableau Prep Builder has different default export settings for .hyper and .csv exports versus Excel exports:










Monday, January 31, 2022

Tableau Prep Builder - TabPy configuration in a V1 credentials.json

 The Tableau Prep Builder credentials.json documentation suggests that for a V1 credentials.json, all you need to specify for TabPy support is the password, if any exists. If you do this with a flow that you created using a recent version of Tableau Prep Builder, though, you'll get a ton of errors stating that some field names do not exist, even if the flow functions perfectly from within Prep Builder itself.

Buried within those errors is likely one that indicates that the TabPy configuration is invalid. I originally assumed that Prep Builder saved the TabPy configuration I had entered into the flow itself, but this is not the case. So, the TabPy configuration info isn't in the flow file, and the documentation doesn't indicate how you should enter this info into a V1 credentials.json, so what do you do?

It turns out that you can apparently mix and match parts of the V1 and V2 configurations just fine. The V1 configuration has no way to provide a server hostname and port number, but the V2 configuration does, e.g.:

{

"extensions": {

    "extensionName": "pythonSupport",

    "regular": {

        "host": "localhost",

        "port": "9004"

    }

}

This can happily sit next to a V1 "inputConnections" section. With the V2 extension configuration entered into the credentials.json file, the flow will run correctly.

Thursday, January 20, 2022

Database name in credentials.json for Tableau Prep Builder

Tableau Prep Builder allows you to create a JSON file with database connection information for data sources associated with a flow. There are two different versions of the credentials JSON format. Version 1 looks like this:

  "inputConnections":[

    {

     "hostname":"https://my.server",

     "contentUrl": "mysite",

     "port":443,

     "username": "jsmith",

     "password": "passw0rd$"

    }

 ]

}

Version 2, which you can use with Tableau Prep Builder 2020.3.1 and later, looks like this:

{

 "databaseConnections":[

   {

    "hostname":"example123.redshift.amazonaws.com",

    "port":"5439",

    "username":"jsmith",

    "password":"p@s$w0rd!"

   }

 ]

}

Unfortunately, it doesn't seem like there's a way in the V2 credentials format to specify the name of the database you want to connect to on the server. If you try to add a field like "database" to the connection JSON, you get an unhelpful error:

Unable to read the connections file. Details:

Unrecognized field "databaseConnections" (class com.tableau.tprep.cli.app.connections.ConnectionInfo), not marked as ignorable (3 known properties: "inputConnections", "extensions", "outputConnections"])

 at [Source: (FileInputStream); line: 18, column: 2] (through reference chain: com.tableau.tprep.cli.app.connections.ConnectionInfo["databaseConnections"])

The error suggests that it's looking for the fields for the V1 format, even though I'm using Tableau Prep Builder 2021.4 and the output includes a line which reads "The connection file is in V2 format." Googling didn't turn anything up that helped - just threads on the Tableau support forums of people having similar issues.

If you try to add the database name to the end of the hostname, like in a connection string URL (e.g. "hostname.com/databasename", you get a slightly more helpful error:

We don't have credentials of all connections in tfl/tflx file. The following connection(s) were not found: <database name>

If you throw caution to the wind and try to connect without specifying a database name at all, you get that error again, but it's less helpful this time.

Luckily, the V1 credentials format still works. The field named "contentUrl" can be used to specify the name of the database that you want to connect to. Replace your V2 credentials.json with a V1-formatted one, and it just works.

Thursday, November 7, 2019

Local Group Policy Order of Evaluation Gotcha

It's once again PCI time here at my workplace. While implementing the whitelisting strategy for Windows Apps I described in a previous post, we discovered that while a default state of "Disallowed" blocks things like Notepad from running when you click them in the Start menu, you can still open them either from the Run dialog, or by double-clicking the .exe directly. This is obviously not acceptable from a PCI/whitelisting standpoint, so we had to find some combination of the new Software Restriction Policy (SRP) method and the old User Configuration GPO method to block everything not on the whitelist.

So, we started with our old GPO-based whitelist, and applied the SRP settings on top. To our surprise, when we logged out and back in, we found that while the SRP was blocking apps correctly, it was behaving as if the User GPO was not there at all! Why would this be, when both are turned on at the same time? Does the Computer-level GPO override the User-level GPO?

On a hunch, I tried it the other way around: I started with the SRP settings, then added the User-level GPO on top. This time, it worked! Apps are blocked by the SRP, and .exes are blocked by the User-level GPO.

Why does this happen? These are local GPOs, so the normal Local-Site-Domain-OU precedence rules do not apply as such in this situation. I have not found any documentation describing the order of evaluation/precedence for local GPOs, but it looks like local GPOs are evaluated in the order you create them.

At least in this case. I can't speak for all combinations of GPOs, but if one order doesn't work for you, it may be worth it to try it another way around to see if that makes the precedences line up to do what you want.

Friday, November 1, 2019

Don't forget the simple stuff: HP multi-function printer automatic document feeder malfunction

This morning, a user reported that their HP LaserJet Pro MFP M277fdn would not scan from the automatic document feeder (ADF) on the top of the scanner. This is the tray that you load paper into for sequential copying or scanning. They reported that when they inserted a piece of paper, the screen displayed a message reading "Document loaded", but then when they went to scan it, the printer instructed them to load the document feeder. So, it appeared that the printer both knew and did not know that paper was inserted.

After verifying that this was true, I started down the troubleshooting ladder. I restarted the printer (no change), hard restarted it by shutting down, removing the power cable, and holding the power button (worked once, but then refused to scan the second time), and cleaned within the top door of the ADF (no change). From here, my mind jumped to software or configuration corruption, so I performed a factory reset of the printer. (This led to the discovery that we have no documentation on how this printer was set up, other than phone pictures I took, which provided us with an opportunity to rekindle our tribal knowledge on the subject.) Alas, after everything was set back up, this too was met with no success.

In the smalltalk that the user and I shared while I was working on the problem, she happened to mention that she was somewhat unhappy with the printer anyways, as the scanner platen often gets dirty. It was then that I realized there was one place I didn't clean: the AFD scanning window on the platen. This area is shown in the picture below, taken from HP's support forum.


I had glanced at this area before, and seen a small line of dirt on the window, but thought nothing of it in this instance; usually, if that area is dirty, you'll get bad print quality, but it has never before interfered with scanning. However, since I was running out of ideas, I decided to go ahead and clean that window, and to my surprise, that appears to have fixed the issue.

Why did that help? The scanner clearly knows it has paper loaded, thanks to the microswitch in the AFD that displays the "Document loaded' message, and yet when it comes time to scan, it thought it was empty. I surmise that there must be some optical sensor mechanism (maybe the scanning head itself?) that checks for the presence of paper in the AFD scanning window, regardless of the microswitch status. Thus, when it tried to check for paper, the dirt on the window prevented it from detecting it, and so the printer was confused.

Whatever the cause, this is a good reminder not to forget to check all of the simple stuff first before going to the hard stuff, even if there's not a large chance that it's causing the problem - because it might just be it.

Tuesday, October 29, 2019

Outlook 2016 Not Loading Images on Windows 8

A user today ran into an issue with Outlook 2016 where it would display HTML emails correctly, but almost all images in those emails were broken links, with the red X in the top-left corner in typical Internet Explorer style. We directed her to instructions on how to set Outlook not to block images in messages, but she sent us a screenshot showing that these were not set, which I confirmed when I visited her.

On Google, I found and attempted some solutions, including clearing the Outlook secure temp folder and confirming that Internet Explorer was not set not to save encrypted pages to disk, but these had no effect.

On a hunch, I copied the link to a broken image out of Outlook into Chrome, and found that it loaded the image without issue. Then, I copied the link into Internet Explorer, and lo and behold, received an error message that IE could not connect to the webpage.

This computer was imaged at a time when TLS 1.2 (and, in this user's case, 1.1) were not enabled by default on Windows 8 in Internet Explorer. Chrome loaded the images without issue because it supports these newer versions by default, but Internet Explorer (and therefore, by extension, Outlook) were not so set, so the hosting servers were refusing their connections, and so not serving the images. Once I set IE to enable TLS 1.1 and 1.2, Outlook began loading images immediately.

Ultimately, we will resolve this issue more thoroughly by refreshing the user's computer with one that runs Windows 10, but as a stopgap until that time, this works.

Tableau, TabPy, and the Case of No Input Rows

 I haven't scientifically confirmed this or anything, but it sure seems like if you pass an empty dataframe to a TabPy script, then no m...