In T401194 we created a sub-page based recommendation provider that uses mock data stored on the `/tone.json` to the articles in question. This will mostly also work as-is in beta. However, for the production release, we will need to get this data from the (Staging) Data Gateway.
That means we will need something similar to the `ServiceImageRecommendationProvider`/`ProductionImageRecommendationApiHandler`, except simpler, maybe we don't even need this separation into two classes for ReviseTone. Also, as opposed to how we do it for ImageRecommendations, for ReviseTone we will not need caching here since we only make a single request to the endpoint. We will add monitoring for the performance of this in T407031 and might add caching later, if we learn that we need it.
The request format will be `/public/ml_cache/paragraph_tone_scores/{wiki_id}/{page_id}/{revision_id}`.requested by `{data-gateway url}/public/ml_cache/page_paragraph_tone_scores/{wiki_id}/{page_id}/{revision_id}`
This can be asserted by trying out the following on a deployment server/testwiki shell:
```
curl https://data-gateway.k8s-staging.discovery.wmnet:30443/public/ml_cache/page_paragraph_tone_scores/testwiki/168753/680406 2>/dev/null |json_pp.
```
The responses will look like:
```lang=json
{
"rows" : [
{
"content" : "rain in spain",
"idx" : 0,
"model_version" : "v1",
"page_id" : 1,
"score" : 0.2,
"revision_id" : 10,
"wiki_id" : "enwiki"
},
{
"content" : "falls mostly on the plainsSchwarzwald Castle offers a wonderful glimpse into medieval life with well-preserved ruins and informative guided tours available in multiple languages. The scenic hilltop location provides excellent views of the surrounding Black Forest, making it a popular choice for families and history enthusiasts. The on-site museum showcases an impressive collection of medieval artifacts, and the castle grounds are perfect for a relaxing afternoon visit. With convenient parking and a charming café serving local specialties, Schwarzwald Castle makes for an enjoyable day trip from Freiburg.",
"idx" : -1,
"model_version" : "v1",
"page_id" : 1,
"score" : 0.3,
"revision_id" : 10,
"wiki_id" : "enwiki"
},
{
"content" : "rain in spain",
"idx" : 0,
"model_version" : "v2",
"page_id" : 1,
"score" : 0.5,
"revision_id" : 10,
"wiki_id" : "enwiki"
},
{
"content" : "falls mostly on the plains",
"idx" : 1,
"model_version" : "v2",
"page_id" : 168753,
"score"revision_id" : 0.6680406,
"revision_id"score" : 100.886,
"wiki_id" : "entestwiki"
}
]
}
```
Similar to T407353#11290512, for this task it is important that the scaffolding is in place, less so that every last detail matches the yet-to-be-built ML pipeline and storage infrastructure.Relevant articles have the `recommendation.tone` tag in CirrusSearch and can be found by: https://test.wikipedia.org/w/index.php?search=hasrecommendation%253Atone
**Acceptance criteria:**
* [ ] By default, we load the recommendations from an internal service via a URL (to be configured in PHP settings)
* [ ] We continue to use the Subpage-based provider on CI, patch-demo, and beta.