Content-Language metadata field in GCS object not allowing ISO-639-2 from API - google-cloud-storage

While trying to update the Content-Language metadata field of an object to ISO-639-2 field from the UI works fine, when trying to do the same from http API, it fails with an invalid argument error. The official documentation page states that ISO-639-1 codes are supported (although the link goes to 639-2).
Any ideas on how to update the Content-Language via http/json for objects in ISO-639-2 ? Or it's possible the UI treats it differently?
Response from GetObject for an object with ISO-639-2 updated via ui
{
"kind": "storage#object",
"id": "XXXXXXXXX/textfile.txt/XXXXXXX",
"selfLink": ...,
"mediaLink": ...,
"name": "textfile.txt",
"bucket": "XXXXXX",
"generation": "XXXXXX",
"metageneration": "2",
"contentType": "text/plain; charset=utf-8",
"storageClass": "STANDARD",
"size": "29",
"md5Hash": "f510qpm7Jh30uKbBcN4e0A==",
**"contentLanguage": "ach",**
"crc32c": "4fnpOw==",
"etag": "COet043XpPcCEAI=",
"temporaryHold": false,
"eventBasedHold": false,
"timeCreated": "2022-04-21T07:56:14.769Z",
"updated": "2022-04-21T07:57:14.321Z",
"timeStorageClassUpdated": "2022-04-21T07:56:14.769Z",
"metadata": {
"gcsfuse_mtime": "2022-04-21T07:56:13.375009661Z"
}
}
Error when trying to set the same value as received in the above call via json
{
"error": {
"code": 400,
"message": "Invalid argument.",
"errors": [
{
"message": "Invalid argument.",
"domain": "global",
"reason": "invalid"
}
]
}
}

I reproduced your case, and it seems like you are right. Content-Language only allows ISO 639-1 language codes for the supported values of this metadata.
When Content-Language was set to “ach” in JSON POST API call it gave me errors “curl: (3) Failed to convert ach” to ACE; string contains a disallowed character” but when set to “en”/ “de”/ “aa” it works fine and gives a HTTP 200 response. I think the logic which works here, checks for ISO 639-1 format.
I have gone through the documentation, and it says clearly “Refer to ISO 639-1 language codes for the supported values of this metadata.” Maybe it routes to ISO 639-2 page, because it contains both ISO 639-1 and ISO 639-2 codes, out of which it mentions it only supports ISO 639-1 language codes. You can check out this documentation as well.
Raise a feature request here so that the Content-Language supports ISO 639-2 language code in API calls.

Related

A combination of supportedLocales and fallbackLocale doesn't prevent UI5 from requesting unexisting i18n-localizations

To configure the i18n functionality in UI5, I'm using the following snippet in the sap.ui5 of manifest.json:
"models": {
"i18n": {
"preload": true,
"settings": {
"bundleName": "webapp.i18n.i18n",
"bundleUrl": "i18n/i18n.properties",
"fallbackLocale": "en",
"supportedLocales": [
"en"
]
},
"type": "sap.ui.model.resource.ResourceModel"
}
},
Thanks to supportedLocales and fallbackLocale I don't expect that UI5 will request unexisting localizations, but in fact I still observe unwanted 404-requests for i18n_en_US.properties:
GET http://localhost:3000/i18n/i18n_en_US.properties 404 (Not Found)
I assumed that the whole idea behind of supportedLocales and fallbackLocale is to reduce amount of requests of localizations, which don't exist and are not specified in supportedLocales.
My questions:
Why UI5 anyway tries to request i18n_en_US.properties although en_US doesn't appear in a list of supportedLocales?
Is it possible to get rid of extra requests for unsupported locales?
I figured out the reason for the unwanted 404-requests.
Initially, I've defined fallbackLocale and supportedLocales for the sap.ui5/models/i18n section, but there is also an i18n section in sap.app, which also requires fallbackLocale and supportedLocales configuration.
The final solution is to add the following code-snippet into sap.app section of manifest.json:
"i18n": {
"bundleName": "webapp.i18n.i18n",
"fallbackLocale": "en",
"supportedLocales": [
"en"
]
},

How to filter marketplace vehicles with Facebook API

I am doing /vehicles?limit=300&filter=[{"field":"vehicle_id", "value":"106892", "operator": "EQUAL"}] and then getting error (#100) For field 'vehicles': Param filter must be a valid WCA rule..
==== Query
curl -i -X GET \
"https://graph.facebook.com/v9.0/{catelog_id}/vehicles?limit=300&filter=%5B%7B%22field%22%3A%22vehicle_id%22%2C%20%22value%22%3A%22106892%22%2C%20%22operator%22%3A%20%22EQUAL%22%7D%5D&access_token=<access token sanitized>"
==== Parameters
- Query Parameters
{
"limit": "300",
"filter": "[{\"field\":\"vehicle_id\", \"value\":\"106892\", \"operator\": \"EQUAL\"}]"
}
- POST Parameters
{}
==== Response
{
"error": {
"message": "(#100) For field 'vehicles': Param filter must be a valid WCA rule.",
"type": "OAuthException",
"code": 100,
"fbtrace_id": "xxx"
}
}
Facebook Ref: https://developers.facebook.com/docs/marketing-api/reference/product-catalog/vehicles/. I cannot find any clear guide how this filter should be.
The filter field should be a valid JSON-encoded WCA rule expression representing the filter to be applied for the edge. You could find reference for this definition here and here (Filter Rules, se also the Example Filter Rules section). In your example, should be something like:
/vehicles?filter={"vehicle_id":{"eq":"106892"}}

cakephp crud plugin return validation errors

When PATCHing to a record using the Crud plugin and Crud.Api listener, a successful PATCH returns a 200 OK with an empty data array in the response.
{
"success": true,
"data": []
}
When validation fails after a PATCH, a 422 Unprocessable Entity with the following response is returned:
{
"message": "A validation error occurred",
"url": "\/admin\/users\/edit\/4.json",
"code": 422,
"file": "\/app\/vendor\/friendsofcake\/crud\/src\/Listener\/ApiListener.php",
"line": 189
}
but I expected something like:
{
"success": false,
"data": [
"errors": [...]
]
}
https://crud.readthedocs.io/en/latest/listeners/api.html#http-put-edit
If success is false a HTTP response code of 422 will be returned,
along with a list of validation errors from the model in the data
property of the response body.
Does the plugin need to be configured to return the errors?
I'm not overly familiar with the Crud plugin, but that response looks like the default CakePHP exception renderer response, so I'd guess that you probably haven't configured your app to use the Crud exception renderer:
config/app.php
'Error' => [
'exceptionRenderer' => \Crud\Error\ExceptionRenderer::class,
// ...
],
Quote from the docs:
Note: However if you are using CakePHP 3.3+’s PSR7 middleware feature the exceptionRenderer config won’t be used and instead you will have to set the Error.exceptionRenderer config in config/app.php to 'Crud\Error\ExceptionRenderer' as following
See Crud Docs > Listeners > API > Exception handler

WireMock: Temp disable stub response

I use WireMock to stub responses from remote server.
In folder wiremock/mappings I have many files that set rules for stub.
Here example:
{
"request": {
"method": "GET",
"url": "/merchant"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"status": 200,
"fixedDelayMilliseconds": 3000,
"bodyFileName": "stub_response.json"
}
}
As you can see, when I get request /merchant then return stubbed response from file stub_response.json.
Nice. It's work fine.
But suppose I need temporary to disable this response. Is it possible to turn off stub response and return real response from remote server?
I need flag like this : "disable" : true
Is it possible in WireMock?
You can disable a rule by using the WireMock admin interface. If you invoke a DELETE command against http://.../__admin/mappings/<guid>, then the mapping will be deleted.
You can get a list of all the guids by performing a GET command against http://.../__admin/
If you want to replace a mapping with a real response instead of a stubbed response, you can add a second mapping that has a lower priority than the stubbed response and that proxies through to the real address. Normally, your stubbed response ill be used, but when you then delete the stubbed response, Wiremock will proxy through to the real address as it will then become the highest priority mapping.
To add a proxy, add the following into the response mapping
"proxyBaseUrl" : "http://otherhost.com",
To set the priority of mappings, add the following into your mapping JSON.
"priority": 1,
There presently isn't a disable attribute to a rule. You can remove a wiremock rule and re-add it later, which would functionally be the same.
If you running Wiremock as a Stand-alone process, you can set it into recording mode, effectively this will proxy all requests to a target URL.
Open http://localhost:8080/__admin/recorder (assuming you started WireMock on the default port of 8080), on that screen you have to enter the target URL and click the "Record" button. Until you stop recording it will make this Wiremock acting as a proxy.
If the recording is not something you actually need, you can dismiss recorded stub mappings. Although this is slightly misusing the Recorder feature it is a fast and easy way to temporarily turn your Wiremock into a proxy, instead of responding with stubs.
Wiremock can select which fixture to use depending on in which state of a scenario it runs. In different states, even for same request, it can have different mappings thus behave in different ways (in one of the states can respond from a fixture, and in another state it can be forwarded to the real API).
Say if there is a Proxy scenario, which is currently in the default Started state, then all the queries will be served by stubs that are not specific to any scenario state.
But if the Proxy scenario is in Active state, and we have a mapping that is specific for that scenario state (requiredScenarioState property), and it has a higher priority than default, then this mapping will be executed for any URI to this Wiremock instance:
{
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"priority": 2,
"request": {
"urlPattern": ".*"
},
"response": {
"proxyBaseUrl": "https://swapi.dev/api"
}
}
The value for response.proxyBaseUrl, will make all the requests to be forwarded to provided host, when this mapping is matched.
Now we need to be able to toggle Proxy scenario to Activated state and back,
so we define two more mappings for POST /proxy endpoint on this Wiremock. They will have even higher priority - 1, so they can override even the mapping for "urlPattern": ".*".
Drop a JSON file containing all three mappings to your wiremock/mappings:
{
"mappings": [
{
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"priority": 2,
"request": {
"urlPattern": ".*"
},
"response": {
"proxyBaseUrl": "https://swapi.dev/api"
}
},
{
"priority": 1,
"scenarioName": "Proxy",
"requiredScenarioState": "Activated",
"newScenarioState": "Started",
"request": { "method": "POST", "url": "/proxy"},
"response": { "status": 201, "body": "Proxy De-activated (Stubs will be used)" }
},
{
"priority": 1,
"scenarioName": "Proxy",
"requiredScenarioState": "Started",
"newScenarioState": "Activated",
"request": { "method": "POST", "url": "/proxy" },
"response": { "status": 201, "body": "Proxy Activated (Will forward all requests)" }
}
]
}
Now you can switch the Proxy scenario to Activated state,
and after switch it back to Started state with:
curl http://localhost:8080/proxy -XPOST
Good thing about this approach that this mapping file can be copied from project to project with minimal changes.

"Resource Not Found" message received when sending a query to Keen IO API

I am using Advanced REST Client tool to test a data pull from the Keen IO API, and think getting the request right, but not getting the data. Getting "resource not found" error. This can also be done via CURL.
Headers: Authorization:
Content-Type: application/json
actual request: GET /3.0/projects//queries/saved/Sponsorships/result HTTP/1.1
HOST: api.keen.io
authorization:
content-type: application/json
Base URL used: https://api.keen.io
Any ideas as to what may be doing wrong?
The saved query name is capitalized "Sponsorships". Make sure your saved query name is lower-cased, not camel or title-cased. To be sure that you are getting the correct saved query name.
Also, you may want to first obtain a list of all saved queries as a reference:
GET /3.0/projects/<project_name>/queries/saved HTTP/1.1
HOST: api.keen.io
authorization: <your_key>
content-type: application/json
You will get something like this:
[
{
"refresh_rate": 0,
"last_modified_date": "2016-12-20T01:09:54.355000+00:00",
"query_name": "",
"created_date": "2016-12-20T01:09:54.355000+00:00",
"query": {
"filters": [],
"latest": 100,
"analysis_type": "extraction",
"timezone": "UTC",
"timeframe": "this_30_days",
"event_collection": ""
},
"metadata": {
"visualization": {
"chart_type": "table"
},
"display_name": ""
},
"run_information": null
}
]
FWIW, I also have seen the "Resource not found" error when writing data to an event if the project is not correctly set up. For example, passing in the wrong project_id or write_key or if the project was deleted from your Keen.io account.