Data Engineering ยท Azure ยท Simple-on-Purpose Side Project

Electricity Prices โ€” Azure

Chosen specifically to be small: fetch a free API once a day, clean it, store it. Ten roadblocks later, still done โ€” just not quickly.

The actual scope

Strip away tooling entirely and this project is four steps: call one free, no-auth API once a day, save the raw response, flatten it into a timestamp/price table, and append it to a growing table while skipping anything already seen. A 30-line script with a cron job, in under an hour, on any machine. Everything below is the distance between that script and the equivalent running inside Azure.

Final architecture

Ingestion via an ADF REST linked service (anonymous auth, no key needed) into bronze/new/. Cleaning via an Azure Function App (Python, Consumption plan, timer trigger) โ€” reads bronze files, flattens, converts timestamps, dedupes, merges into a single growing silver/prices.parquet, archives and deletes the source files. Synapse was deliberately ruled out for the cleaning step before it was ever attempted: a 17-row job would need the exact same Spark pool, cold-start delay, and quota contention risk as a 2.7-million-row one โ€” the architecturally correct call was Azure Functions instead.

What was genuinely easy

Two things matched the "should be simple" expectation completely: choosing the aWATTar API (no key, no registration, one clean endpoint), and the ADF ingestion pipeline itself, built without real issues by reusing patterns already learned on Bee Haven.

Ten roadblocks, none of them about the actual problem

None of what follows came from the logic being hard or the API being unreliable โ€” every one of these was Azure-platform-specific tooling friction, hit while building something whose actual logic is four bullet points long.

Screenshot of the VS Code setting up the Function App Screenshot of setting up the Function App through the VS Code.

Once all of it was resolved, the function ran correctly on the first genuine attempt: authenticated, read four bronze files spanning multiple days, deduped and merged into a 32-row Silver table, archived the originals, completed in 943ms.

Screenshot of the Function App in the Azure Portal Screenshot of the deployed Function App in the Azure Portal.
Comparison to Bee Haven: fewer and smaller individual roadblocks than the ADF/Synapse identity saga โ€” but proportionally, given how much smaller this project's actual scope was, the friction-to-substance ratio was arguably worse. A 30-line script took longer to get running in Azure than it would have taken to write from scratch with no cloud involved at all.

The trigger bug, again

The scheduled ingestion trigger, correctly configured and confirmed "Started," did not visibly fire over several days of observation โ€” resulting in partial-day Silver data (17โ€“20 rows instead of the expected ~24) rather than missing days outright. This is the exact same undocumented ADF trigger bug hit independently on Bee Haven. The dedup/merge logic itself was confirmed correct against the local Docker version, which uses its own scheduler and reliably captures a full 24 rows/day โ€” isolating the gap specifically to ADF's trigger reliability, not the cleaning logic.

The dashboard: skipped, on purpose

A dashboard on top of the Azure Silver data was considered as a natural final step โ€” a working local Plotly version already existed as proof of concept. Decided against building an Azure-connected version for a plain reason: Power BI Desktop is Windows-only, and this entire project was built on a Mac. With both Azure pipelines genuinely complete and working, the honest call was that neither the web-based Power BI Service nor pointing the local script at the Azure Parquet file added enough value to justify more time. Not a technical dead end โ€” a conscious "the core project is done, this was optional polish" decision.

Where it stands

Ingestion, cleaning, and merge/dedup logic all individually proven correct. Automatic daily firing could not be confirmed, for the same documented platform reason as Bee Haven. Project closed out as done, with the trigger limitation and the skipped dashboard both explicitly documented rather than left unexplained.

๐Ÿ““ Full technical deep-dive: all ten roadblocks, symptom โ†’ root cause โ†’ fix