An unfortunate hole in my portable brain

This morning I got an email from one of my business partners. She’s out of town on a job and needed our FedEx number sent to another lab so they can ship some samples to us. No problem, I thought, I’m sure I have it on my phone. But no, that was one of those things I always meant to save on my phone but never got around to. My partner thought she had it on her phone, too.

Here are the things I have gotten around to saving to my phone:1

Some of these may seem silly, but I’ve made use of almost all of them at one time or another. A couple of years ago, when my mom moved to a nursing home and I needed to close out certain services at her house, I learned that the phone service was still in my dad’s name. She’d never changed it when he died ten years earlier. So I used his SSN (along with my grandmother’s maiden name, which wasn’t saved to my phone but didn’t need to be) to impersonate him with the phone company and get the account closed. That was a little weird.

(I have since learned that friends my age commonly pretend to be their aging parents to deal with customer service reps. I am, however, the only one I know who pretended to be a dead parent.)

As I look through the list, I see that I still haven’t added things I’ve always meant to. In particular, apart from the FedEx number, I should be keeping the account numbers for various insurance policies.

Up until recently, I’ve had (or intended to have) all of this stuff in secure notes in 1Password. As part of my shift to a more iCloud-based system, I’ve copied them over to locked notes in the Notes app. There have been advantages and disadvantages to the change.


  1. And iPad and Macs, but it’s mostly when I’m out with just my phone that I need them. 


License files for Airtable

Shortly after my software license post went up, Jezper Söderlund tweeted me a very good question: How do you handle software that uses a license file instead of a license key? Turns out there’s a simple answer, and I needed it.

After exporting the licenses from 1Password and importing them into Airtable, I had noticed that the entry for Witch, the better-than-stock app switcher from Many Tricks, had no license key. Weird, I thought, but I didn’t follow up on it. When I saw Jezper’s tweet, I realized why.

Witch does, in fact, use a license file instead of a license key to authorize its use. The license file is buried in the Application Support subfolder of your Library folder. 1Password has a system for adding attachments to software license entries, and I had done that when I bought Witch. Unsurprisingly, the file attachment didn’t get exported to the CSV file. I was a little surprised, though, that the CSV didn’t have a field to indicate there was an attachment for that entry.

In any event, now that I knew I needed to handle file attachments, the solution was simple. I added a new field to my Airtable database and chose the Attachment field type.

Airtable field type

With this field added to the database, it was easy to drag Witch’s license file into Airtable. When you click on an empty attachment field in Safari on the Mac, the field tells you it’s ready to have a file dragged and dropped onto it.

Airtable attachment field in Safari

I scrolled through all the other software licenses in 1Password to see if any others had license files. They didn’t, but now I’m ready to handle any new apps that do.


Reorganizing software licenses

As part of the slow process of moving my myself away from 1Password to iCloud Keychain, last week I exported the list of software licenses and put them in a database. This took more time than I expected, as I tried out different ways to organize the list.

I have, by the way, nothing against 1Password. It’s a great program and has been a big help to me for many years. But as I try to simplify my computing setup, it seemed best to avoid having a separate program that, as I use it, largely replicates a function of the operating system. Especially when that separate program has moved to a subscription service—I’d rather use that money to pay for software that’s substantially different from what Apple provides.

One of 1Password’s functions that isn’t in iCloud Keychain is the list of software licenses.

1Password software licenses

There are a couple of ways to get the license data out of 1Password:

I started out doing it the iOS way and quickly decided the Mac way would take less time for the several dozen licenses I needed to export. Whichever method you choose, you won’t be pleased with how much fiddling you have to do.

With the data in a Numbers spreadsheet, I figured there were three options:

  1. Just keep it in a spreadsheet. That’s not a bad format for this kind of data, and I could make it available on all my devices by saving it to iCloud Drive.1
  2. Export the spreadsheet out to a CSV file and import that into a database. Airtable would be my choice, as it looks good and works across platforms. I’m not entirely sold on its security2, but software licenses don’t strike me as especially damaging if they get hacked.
  3. Export the spreadsheet to CSV and then turn it into formatted text that can be kept in Notes. This is also available on all my devices and notes have the additional advantage of being lockable. This little Python script reads the CSV and formats it for a note:

    python:
     1:  #!/usr/bin/env python
     2:  
     3:  import csv
     4:  
     5:  print("Software licenses\n")
     6:  with open('1p.csv') as csvfile:
     7:    reader = csv.DictReader(csvfile)
     8:    for row in reader:
     9:      print(row['app'])
    10:      for f in reader.fieldnames[1:]:
    11:        if row[f]:
    12:          print("{}: {}".format(f, row[f]))
    13:      print()
    14:         
    

    It opens the CSV file named 1p.csv, and writes out every record in its own paragraph. The first line is the name of the app, and the subsequent lines are all the other fields in

    key: value
    

    format. After importing to Notes, it looks like this:

    Software licenses in Notes

    The disadvantage of using Notes is that I have to type everything in myself when adding a new entry. Also, I can’t just add it to the bottom if I want the list to stay alphabetized.

Although I’ve done all three of these to see how they work, I think I’ll stick with the Airtable solution. It’s easier to scroll through than Notes and has a single-entry view that Numbers doesn’t provide, which is especially convenient when using an iPhone.

Single entry in Airtable


  1. And password protect it, too. Thanks to Teddy Svoronos for reminding me. 

  2. No particular reason for this; I’m just generally skeptical of cloud security, especially with things I’m not paying for. 


Airtable

I first heard of the Airtable database about a week ago from this Twitter thread involving Christina Warren, Ed Cormany, T.J. Luoma, and Rosemary Orchard. Already it’s my primary way of accessing my main projects database from work.

Airtable is a cloud-hosted database1 that can be accessed through a web interface, an iOS app, or programmatically through an API. I haven’t used the web interface much, but the iOS app is very well designed and the API is a wonder of clarity.

The database I moved into Airtable is a table of projects at work that I’ve been using in one form or another for over 20 years. It’s basically a list of jobs, storing the following information for each job:

For many years this was just a plain text file, one record per line and the fields separated by pipe (|) characters. A small set of Perl scripts were used to add and extract information. Then I imported it into a SQLite database and rewrote the scripts in Python using the sqlite3 library.

As I found myself wanting to search the database on my phone and iPad, I moved the database file to iCloud Drive and wrote some scripts in Pythonista to do the searching. This worked, but it was a little clumsy and the results, while correct, were ugly. I didn’t really want to put in the effort to make the output prettier, but I was resigning myself to get down to it when Airtable appeared in my Twitter feed.

It took basically no time to export the data from SQLite and import it into Airtable. Now I have a nice looking view of the project information (well, it’s nice looking when I haven’t scrambled the fields for anonymity).

Airtable database on iPhone

It’s easy to search by tapping the magnifying glass, but I often find the information I want (who’s the client on Project X? what project did I just open for Client Y?) sitting right in front of me when I open the app. The other fields can be seen by scrolling to the right.

When I first imported the data, all the fields were treated as either text or numbers. Airtable has a variety of other field types that can specialize these two generic types:

Airtable field types

Within the Number type, you can choose between integer and floating point, which can be quite handy.

To reduce the clutter, I have a filter that shows only the latest projects.

Airtable filter

And I sort them by number in inverse order because the projects I’m most likely to be looking for are the most recent.

Airtable sort

The API is easy to understand and has possibly the best documentation I’ve ever seen. The docs are formed with examples that are specific to your database; they include your fields and your records, not some made-up example that means nothing to you.

Airtable API example

Airtable doesn’t provide a Python library, but it’s easy to use the API through the Requests and JSON libraries:

python:
 1:  # Add record to Airtable database.
 2:  airURL = 'https://api.airtable.com/v0/ABC987654321/projects'
 3:  airHeaders = {
 4:    'Authorization': 'Bearer 12345ABCDE',
 5:    'Content-Type': 'application/json'}
 6:  payload = {'fields': {
 7:    'name': 'New Project,
 8:    'number': 9999,
 9:    'client': 'Jane Q. Client',
10:    'clientref': 'JQC1234',
11:    'directory': 'new.project',
12:    'box': 0,
13:    'email': 'jane@company.com'}}
14:  r = requests.post(airURL, headers=airHeaders, data=json.dumps(payload))

The identification code in the URL is specific to the database, and the authorization code that goes in the header is specific to the user. The JSON library’s dumps function takes a Python structure—in this case a nested dictionary—and turns it into a JSON string for POSTing. The response is stored in the r variable, from which we can extract the JSON data that tells us whether the request was a success.

For the small data sets I typically work with, the free version of Airtable, which limits you to 1200 records per database, is sufficient. I’m a little leery of using free services for job-critical data—I don’t want something I rely no to end up with the dreaded sunsetting post on Medium—but Airtable seems to be well funded for now. Also, I’m still keeping and updating the old SQLite database for safety.

With my first Airtable database under my belt, I’m eager to add more. Airtable markets itself for teams (because everything markets itself for teams nowadays), but don’t let that stop you from using it for personal databases. I have a few inventories for both work and home that could really use the structure of a database behind them.


  1. They say it’s “part spreadsheet, part database,” but aren’t all databases part spreadsheet (and all spreadsheets part database)?