Skip to content

feat: add the cooking history ("last cooked") - #265

Open
FezVrasta wants to merge 1 commit into
miaucl:masterfrom
FezVrasta:feat/cooking-history
Open

FezVrasta wants to merge 1 commit into
miaucl:masterfrom
FezVrasta:feat/cooking-history

Conversation

@FezVrasta

Copy link
Copy Markdown
Contributor

Closes #214.

You asked in the issue for someone to find the necessary requests — here they are, plus the implementation.

The endpoint

The organize service publishes it in its own .well-known/home document, so it slots straight into the existing discovery mechanism:

organize:api-cooking-history -> https://cookidoo.de/organize/{lang}/api/cooking-history
GET /organize/{language}/api/cooking-history
accept: application/vnd.vorwerk.organize.cooking-history.mobile+json

Response:

{"userId":"","entries":[
  {"details":{"timestamp":"2026-09-05T05:31:47.529Z"},
   "recipe":{"id":"r59322","title":"","totalTime":"5100.0","type":"VORWERK",
             "locale":"","assets":{"images":{"square":"","portrait":"","landscape":""}}}}
]}

There is also an organize:api-cooking-history-multiple rel at .../cooking-history/multiple.

What I found probing it

Verified against the live API with a real account:

  • No pagination. ?page= and ?limit= are accepted but ignored — the whole history comes back in one response. So get_cooking_history() has no page argument, unlike the collection methods.
  • Ordering is newest-cooked first.
  • totalTime is a stringified float of seconds ("5100.0"), not the plain int the planning endpoints return. Normalised to int here.
  • Content negotiation: any other Accept 406s with Acceptable representations: [application/vnd.vorwerk.organize.cooking-history.mobile+json, application/json]. The mobile variant is used, matching the existing custom-list/managed-list call sites; application/json returns the same entries plus legacy image fields.
  • OPTIONS reports Allow: POST,GET,HEAD,OPTIONS on cooking-history and Allow: POST,OPTIONS on cooking-history/multiple.

Scope

Only the read path is implemented. The POSTs presumably record a cook, but confirming that means writing to a real account's history, so I left them out rather than shipping something untested — happy to add them if you want to verify separately. Both are documented in docs/raw-api-requests/get-cooking-history.txt.

API

history = await cookidoo.get_cooking_history()
# [CookidooCookingHistoryEntry(id="r315976", name="Torta caprese",
#     cooked_at=datetime(2026, 9, 5, 5, 31, 47, 529000, tzinfo=UTC),
#     total_time=5100, thumbnail="…", image="…",
#     url="https://cookidoo.it/recipes/recipe/it-IT/r315976"), …]

Test

8 new unit tests (happy path, empty history, entry without images, unparsable timestamp, request/auth/parse errors), plus a smoke test asserting shape and ordering. Full suite: 366 passed, ruff and mypy clean. Also verified end-to-end against the live API through live discovery: 16 entries, correctly ordered, all timestamps tz-aware.

The snapshot update in well-known-snapshots/latest.json is the drift-check script's own output after adding the rel to ENDPOINT_RELS.

🤖 Generated with Claude Code

https://claude.ai/code/session_015XfphwxLWbVT1k2bxXGRcF

Closes miaucl#214.

The recipes an account has cooked are served by the organize service,
which publishes them as `organize:api-cooking-history` in its
`.well-known/home` document:

    GET /organize/{language}/api/cooking-history
    accept: application/vnd.vorwerk.organize.cooking-history.mobile+json

Adds `Cookidoo.get_cooking_history()` returning a list of
`CookidooCookingHistoryEntry` (recipe id/name/images/url plus the
`cooked_at` timestamp), newest cooked first.

Notes on the endpoint, verified against the live API:

* It takes no pagination parameters. `?page=` and `?limit=` are accepted
  but ignored and the whole history comes back in one response, so
  unlike the collection endpoints this method has no `page` argument.
* `totalTime` arrives as a stringified float of seconds ("5100.0"),
  not the plain int the planning endpoints return; it is normalised to
  an int here.
* Requesting another representation 406s, naming
  `...cooking-history.mobile+json` and `application/json` as the only
  acceptable ones. The mobile variant is used, matching the existing
  custom-list/managed-list call sites.
* `OPTIONS` reports `POST,GET,HEAD,OPTIONS` here and `POST,OPTIONS` on
  `.../cooking-history/multiple`. Only the read path is implemented;
  recording a cook is left out rather than shipped untested.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XfphwxLWbVT1k2bxXGRcF
@github-actions github-actions Bot added the 🧪 testing Pull request that adds tests label Sep 8, 2026
@codecov

codecov Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.65217% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.84%. Comparing base (f3dad89) to head (5e117ad).

Files with missing lines Patch % Lines
cookidoo_api/helpers.py 86.66% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##            master     #265      +/-   ##
===========================================
- Coverage   100.00%   99.84%   -0.16%     
===========================================
  Files            8        8              
  Lines         1259     1305      +46     
  Branches       113      115       +2     
===========================================
+ Hits          1259     1303      +44     
- Misses           0        2       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🧪 testing Pull request that adds tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add my recipes to API

1 participant