Getting Past The Cloudflare Wrangler CLI NPM Installer Errors

Update: If this is an option for you, an easier approach is to use cargo to install the Wrangler CLI. If you’ve tried installing via NPM already, clear out any existing files by running npm uninstall -g @cloudflare/wrangler.

In trying to install the Cloudflare Wrangler CLI via npm, I first pasted in exactly as the documentation said:

npm i @cloudflare/wrangler -g

This threw a long list of errors, with a recommendation at the bottom of the list saying:

npm ERR! The operation was rejected by your operating system.

npm ERR! It is likely you do not have the permissions to access this file as the current user

npm ERR! 

npm ERR! If you believe this might be a permissions issue, please double-check the

npm ERR! permissions of the file and its containing directories, or try running

npm ERR! the command again as root/Administrator.

Seeing this, I threw a sudo in before the command, only to be greeted with this error message:

{

  errno: -13,

  syscall: 'mkdir',

  code: 'EACCES',

  path: '/Users/[USERNAME]/.wrangler'

}

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! @cloudflare/[email protected] postinstall: `node ./install-wrangler.js`

npm ERR! Exit status 1

npm ERR! 

npm ERR! Failed at the @cloudflare/[email protected] postinstall script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Squinting at the message, I saw that the installer had failed to create a directory named “.wrangler” in my home directory. So I pulled up a new terminal window and ran the mkdir .wrangler command myself.

Running the sudo install command again, I instead got this:

{

  errno: -13,

  syscall: 'mkdir',

  code: 'EACCES',

  path: '/Users/[USERNAME]/.wrangler/bin'

}

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! @cloudflare/[email protected] postinstall: `node ./install-wrangler.js`

npm ERR! Exit status 1

npm ERR! 

npm ERR! Failed at the @cloudflare/[email protected] postinstall script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Progress, yes, but another mkdir issue. So I repeated what I did and created a “bin” directory within the “.wrangler” directory I had just created. This did the trick and the installation completed successfully.

The Terminal output showing Cloudflare Wrangler was successfully installed via npm. What follows is a transcription of the raw output. /usr/local/bin/wrangler -> /usr/local/lib/node_modules/@cloudflare/wrangler/run-wrangler.js > @cloudflare/wrangler@1.19.0 postinstall /usr/local/lib/node_modules/@cloudflare/wrangler > node ./install-wrangler.js Downloading release from https://workers.cloudflare.com/get-npm-wrangler-binary/1.19.0/x86_64-apple-darwin wrangler has been installed! + @cloudflare/wrangler@1.19.0 added 22 packages from 9 contributors in 1.851s
The Terminal output showing Cloudflare Wrangler was successfully installed via npm.

In short: Run mkdir yourself to create a “.wrangler” directory within your home directory. Then create a “bin” directory within that “.wrangler” directory you created.

Resolving Issues Authenticating SA360 Web Queries In Excel

Search Ads 360 web queries are a phenomenally useful feature. For the most part, they are easy to use and enable a broad number of users to set up complex reporting workflows for themselves.

A frustration that several people, including myself, have encountered over the past few months is that it’s become effectively impossible to sign in to your Google account within the Excel mini-browser you use to create a web query connection in your sheet. What we saw were a number of script error dialogs and then a message from Google saying we were using an insecure browser.

Historically, if you weren’t able to sign in within the Excel mini-browser, you could just sign in to your Google account in Internet Explorer. The Excel mini-browser, being an instance of Internet Explorer, would just inherit this authenticated state and let you pull in your web query report.

It’s been a frustrating problem to figure out, but earlier today—while working with a friend to resolve it—we discovered what seems to be the consistent solution. If you have the patience to trawl through things, you’ll find it mentioned in this forum thread as well.

Make sure you have closed all Excel windows. Pull up “Internet Options” from the Internet Explorer settings menu. In the “Security” tab, uncheck the box for “Enable Protected Mode”. Click “Apply” and close the window. Then relaunch Internet Explorer. After you do so, if you’re not already signed in to your Google account, do so in Internet Explorer. You should now be able to create and refresh web queries in Excel without issues.

Pandas to_csv Encoding Error Solution

As these things typically go, last week I ran into an unusual error when using DataFrame.to_csv:

/usr/local/lib/python3.6/dist-packages/pandas/io/formats/csvs.py in _save_chunk(self, start_i, end_i)
354 )
355
--> 356 libwriters.write_csv_rows(self.data, ix, self.nlevels, self.cols, self.writer)

pandas/_libs/writers.pyx in pandas._libs.writers.write_csv_rows()

UnicodeEncodeError: 'utf-8' codec can't encode characters in position 31-32: surrogates not allowed

The error was unusual to me because I was using Pandas in a way I typically would, on data that should not have been meaningfully different in type from the data sets I’ve used it on. This was a real head-scratcher that no number of Stack Overflow answers, Github comments or blog posts seemed to offer a good answer to.

With a lot of trial and error, it appeared the raw data itself was the problem, not any weird side effect of re.sub or other munging operations I was doing. In short, I needed to clean up the encodings for every field in the entire DataFrame. Here’s the solution, if you’re in the same boat:

new_df = original_df.applymap(lambda x: str(x).encode("utf-8", errors="ignore").decode("utf-8", errors="ignore"))

I entirely expect this approach is imperfect and non-optimal, but it works. I’d be happy to hear suggestions.

 

Relevant reading:

  1. pandas.DataFrame.applymap
  2. String encode()
  3. String decode()
  4. Python standard encodings

How I Created A Robot Researcher With Zapier, Evernote and DuckDuckGo

An idea I’ve been noodling for quite some time (going back several years to my junior year at TCU) is a tool that automatically researches topics in the background for you. One such tool existed for a brief period of time, Dunno, but the company now appears defunct.

Earlier today, I decided to take a stab at setting up a complex multi-step zap in Zapier that would tie into Evernote to pull the subject and post the result. I figured DuckDuckGo would have some sort of API to access their instant answers and found that they do indeed. Zapier’s Code action allows you to run Python code, but doesn’t allow you to import additional libraries. To work around this, I found Mashape (listed on DuckDuckGo’s API page) fully sufficient.

The implementation details are below:

#1: Create a trigger to watch for new notes in a specific Evernote notebook.

#2: [Optional] Create a filter to only proceed with notes bearing a specific tag. You can skip this if you want the zap to run with any new note added to a certain notebook.

#3: Create a code action to fetch the DuckDuckGo results as JSON. I used Python. Sample code below.

query = input_data[“note”].replace(” “,”+”)

request_url = “https://duckduckgo-duckduckgo-zero-click-info.p.mashape.com/?format=json&no_html=1&no_redirect=1&q=” + query + “&skip_disambig=1”

response = requests.get(request_url,
headers={
“X-Mashape-Key”: “YOUR_KEY”,
“Accept”: “application/json”
}
)

output = response.json()

#4: [Optional] Create a code action to compile a link to launch a DuckDuckGo search for your topic. I create this mostly for convenience; if I wanted to dig further into a topic, I could easily click the generated link. Sample code below.

query = input_data[“note”].replace(” “,”+”)compiled_link = “https://duckduckgo.com/?q=” + query

output = [{‘search_link’: compiled_link}]

#5: Create an action to append the results to your note (or create a new note with the results).

 

I have a long list of topics I am idly interested in. I created this automated researcher to help feed those curiosities. If, after reading the results, the topic continues to pull on my mind I am free to devote my time to researching it deeper. If not, I can just file it away with the result included in case I ever want to look it up again.

I’m aiming to create a similar task using the Email Parser trigger to let me email topics to my automated researcher and have it save its results to a new Evernote note.

Google Cloud Platform OAuth Redirect URI Error Resolution

While working on installing an Apps Script to a Google Sheet, one step in the instructions required me to add the script project’s redirect URI to the list of authorized OAuth URIs in the supporting GCP project. Despite being the owner of the project, GCP refused to save my update to the authorized redirect URIs list, presenting me instead with this super informative error message about not having permission to perform the action:

I scoured the internet for an answer and came up with nothing even close to helpful. At my wit’s end, I decided to give a shot to just creating credentials for a second web application within my GCP project, inputting the necessary redirect URI from my Apps Script project. Lo and behold, this worked and I was successfully able to complete my implementation of the aforementioned script.

The steps are straightforward, but if you do encounter an issue with saving an update to your list of authorized redirect URIs for a web application in GCP, here they are spelled out:

On the “Credentials” page for your GCP project, select Create credentialsOAuth client ID.

Fill out the form to create a new client ID, with “Web application” under Application type, some relevant name and the authorized redirect URI you need to use. Click Create and you will be given a client ID/client secret pair to use as needed.

I hope this post helps shorten your search for a solution if you ever encounter this permissions issue!

Producing A Video On iPad

Among several projects I’m kicking around is a YouTube channel sharing apps I like and other things relevant to computing platforms. Today, I published my first video on the channel.

It was very spur-of-the-moment. I was checking out watchOS 3—which I wasn't able to try as a public beta unlike iOS 10—and began composing a tweet about the app launch speed improvements in the update. I thought about attaching a video to the tweet, so I pulled up the camera on my iPad Pro that was propped up in front of me.

I took a few takes of me jumping around apps on my Apple Watch until I was satisfied with the composition. When I played back the video, I didn't like the background noise that had been picked up. So, I popped into iMovie and silenced the video. Flicking through the audio options, I picked a pleasant background score and edited it to fade out toward the end of the video.

As I exported the video to my camera roll, I thought I might as well upload it to the aforementioned channel. The result is here to watch.

The entire process took less than 30 minutes from start to finish. This speed and simplicity is one of the things I love about working on iOS.

Planet Money: The Podcast I Recommend Most

I’m considering publishing a Medium post about how NPR’s Planet Money deeply impacted my world-view. Whether you have a long list of podcast subscriptions or have never listened to one before, I recommend giving Planet Money a shot.

Simply put, each episode discusses some way money, trade and economics impact our world. If that sounds boring, trust me and give it a shot. Heck, scroll through their catalog of episodes and find the one that most piques your interest. The episodes are short—and absolutely fascinating and educational.

Planet Money taught me a lot. I think you might find it useful—or simply interesting—too.

P.S. If you own an iOS device, I recommend Overcast as a podcast client.

Website Updates on iOS

If you follow me on Twitter, you may have noticed a little tweetstorm I had earlier tonight as I made some updates to my website.

While the homepage at varunpramanik.com is a pretty basic and lightweight page, I have a tendency to go a little nuts over the details on it (have a look at the source and stylesheet). I’m therefore happy that I was able to complete every task for the edits to my satisfaction on my iPad.

To start, I saved the logos for each company/service to Photos and then pulled them up in Pixelmator to get the hex codes for their dominant colors using the color picker for the brush tool. I used these hex codes to give the links a sense of character and relevance to their destinations.

I used Drafts as a Slide Over app to drop notes, like the aforementioned hex codes.

I grabbed copies of my website assets from my cloud storage using Documents, sending them to Transmit for management and Coda editor access.

I did the bulk of my code editing in Coda (I made some minor tweaks in Transmit’s built-in barebones text editor). Coda has some great syntax highlighting and preview features, though it has frustrating backspace and cursor movement behaviors.

Finally, I uploaded my assets via FTP to my host using Transmit, whose drag-and-drop uploads and permissions management I absolutely love.

Check out the end result.

Markdown Tables in Ulysses on iOS

After hearing much about Ulysses from people whose opinions I trust, namely Federico Viticci, I decided to give it a try for a writing project. This post is a slight distraction aside in the midst of that project.

As I was writing, I figured it would be best to lay out some data in a table. Unfortunately, the Markdown variants supported by Ulysses don’t support a MultiMarkdown-like syntax for tables.

That’s where iOS comes in. More specifically, that’s where Workflow shines. I figured I could meet my needs using a combination of a Workflow action extension and Ulysses’ Markdown XL raw source syntax (~…~). The Workflow I created takes Markdown-formatted text, converts it to HTML and places it on my clipboard. While I aim to use it to create HTML tables, you could technically use this workflow in any instance where you need to convert Markdown to HTML via an action extension.

Here’s how it looks:

  1. I create a MultiMarkdown-formatted table.

    Screenshot of a sheet in Ulysses with a block of MultiMarkdown table-formatted text.
  2. I select the block of text and hit the share button.

    Screenshot of a sheet in Ulysses with a block of MultiMarkdown table-formatted text selected, displaying the iOS text action pop-up.
  3. I run the workflow.

    Screenshot of the Workflow action extension running my workflow to convert the MultiMarkdown-formatted text to HTML code.
  4. I paste and replace the text with the HTML code on my clipboard.

    Screenshot of a block of HTML table code, which was pasted from the clipboard to replace the MultiMarkdown-formatted table text.
  5. I wrap the HTML code with Ulysses’ raw source syntax (~…~)

    Screenshot of HTML table code wrapped in Ulysses’ syntax for raw source.
  6. Voilà.

    Screenshot of a formatted HTML preview of the Ulysses sheet, displaying the table code rendered appropriately.