Nicely done, it looks very useful indeed. And thanks for making the source code available! I find your use of sqlalchemy especially useful for my selfish purposes - I always wanted to figure out how to use it (by looking at a working example), but was too lazy to research it until I stumbled onto your project.
I'll have an in-depth look over it and may come up with some suggestions later on, that is, if you don't mind getting some feedback :).
Your RESTful API skills are probably better than mine anyway, but I've also been collecting and storing API data using python scripts for some time now, so I'm aware of several quirks and traps GOG API data can shove at you - should you find yourself wondering about anything at any point, do reach out to me, I'd be glad to help out if I can.
SQLAlchemy is one of the best designed libraries I've ever used, I'm never going back to writing regular SQL. I'd love to get some more detailed feedback, especially from someone with as much insight into the API as you. There are probably a lot of similarities between our codebases, if you want to collaborate I'm definitely up for it. Anyway, thanks for the offer to help out.
Yeah, I've not found an easy way to do it yet (there seems to be no link between the packages and their contents that I can find).
There is a link if you add two packages to the cart and they both contain the same game. At checkout it tells you that x already contains y, but only as a string without IDs. I could use WinterSnowfall's data to match up the titles to IDs and then manually fix up any mistakes. It's a really messy solution though and requires a proper script which I haven't gotten around to so far.
The timestamps originate from Unix and have been in seconds since 1975. Milliseconds wasn't possible because it had to fit into a 32bit integer and that would have been just around 50 days of date range. It's the default in Python, PHP, Ruby, C++, C, C# and many more, the Java languages indeed seem to be the outliers.