In my opinion, frozenfrogs, that is perfectly fine, and gets results. Technically, what you've done, is to achieve a purpose by getting the students use existing modules to experiment and fulfill a certain task, with minimal programming required (since a buttload of examples of how to do those things already exist).
I personally don't really call it programming, but experimentation. It is like engaging students interested in robotics and mechanisms by using Lego Mindstorms or Technic.
It gives a fundamentally intuitive grasp at the subject, without going into the art/science/knowledge of it. For the purpose you use it, this is absolutely perfect in my opinion.
Thing is, it does not by itself help them learn programming at all, the underlying logic and approaches different programming languages have, or how the entire stack is constructed; only an intuitive grasp. So, when discussing in a context where the assumption is that we talk about programming and not about initial experimentation by non-programmers, the answers and guidance you get will not match your expectations/experience/situation. Context matters.
The main issue I've had, is that self-learners rarely need to understand those underlying structures and differences, until it is almost too late. You get things like huge effort spent in micro-optimizing some functions that are rarely run, while the project itself uses very inefficient algorithms; and could be made an order of magnitude more efficient by rewriting it with a better model and algorithms. It takes effort to un-learn such habits, and to learn the more important stuff, like writing maintainable code with useful and insightful comments (that do not describe what the code does, but what the programmer intent is).
(Note, however, that I have not taught programming per se as a job; only some specific workshop-type courses a long time ago. I do help others learn at StackOverflow, though.)
I haven't encountered (but not looked for, either!) for really good programming guides one could follow, because I think a mixed approach works better. You tickle their intuition enough to get them interested, and then introduce the related concepts, so they'll explore them just enough to know they're there. Like foreshadowing, or Chekov's Gun. At the point where they have the prerequisite skills or capability to understand (integrate into their existing knowledge base!), advanced concepts, structures, and algorithms are explored in detail; especially via deconstructing/constructing example code.
I did have a hobby project last year, for a web workshop type of course, using a microcontroller (with native USB support, under Arduino) and Python 3 and Qt or GTK to create an interactive graphical user interface to control something on that microcontroller. It fell through (test subject bowed out, due to "lack of time"; I only have a rough skeleton, as I intended to flesh it out using that test subject), but the intent was to do exactly what I described above. The Arduino part is experimentation with existing modules, using USB Serial to talk to the GUI application. Different programming languages are used intentionally, although it is much steeper learning curve for the learner. In Python, a separate thread is used to handle the serial communications, and one or more Queues to talk with the GUI. This way the GUI won't stall, even when communication/computation takes a while. This is on Linux, so additional sysadmin stuff like device/file/directory ownership, character devices, and udev rules need to be discussed to get things working.
When I myself first learned programming some thirty-odd years ago, on a C64, a friend and I had to painstakingly copy BASIC from a magazine by hand. I remember how I discovered that using a screenful of ╱ and ╲ characters, one could create mazes. Alas, no internet (no modem for BBS access either) meant I only discovered proper maze-creating algorithms a decade later... Some will never take the leap from copying existing code or plans to creating their own, but IMO, that leap is the difference between experimentation or playing in the Arduino environment, and proper programming.