Get current deployed timestamp in AppEngine/Go - google-app-engine

Can I get the deployed timestamp of current application version in AppEngine/Go?
It seems helpful, but not sure how to implement in AppEngine/Go application code.
AppEngine: Get current serving application version
https://godoc.org/google.golang.org/appengine
https://cloud.google.com/appengine/docs/admin-api/v1beta2/reference/apps/modules/versions

From this link AppEngine: Get current serving application version, the suggested answer is written in python
os.environ['CURRENT_VERSION_ID']
Above code is trying to retrieve the environment variable with name CURRENT_VERSION_ID, Equivalent code in go would be:
import (
...
"os"
)
...
versionText := os.Getenv("CURRENT_VERSION_ID")
According to one of the comments, the result would be in this format my-version.383096322806301043, you should use strings.Split method to split it by ., eg:
import (
...
"strings"
)
...
timestampString := strings.Split(versionText, ".")[1]

Related

CakePhp 4.x basic Authentication

I am following the CakePHP 4.x tutorial to the letter (as far as I can see) until chapter "CMS Tutorial - Authentication".
Half way through "Now, on every request, the AuthenticationMiddleware will inspect the request session to look for an authenticated user. If we are loading the /users/login page, it will also inspect the posted form data (if any) to extract the credentials."
When I try to access articles or users I get an error:
( ! ) Fatal error: Interface
'Authentication\AuthenticationServiceProviderInterface' not found in
C:\wamp64\www\cake\src\Application.php on line 41
I have tried to figure out why this would be, but I cannot find it. I have tried looking up the same problem on the internet, no dice. Not even a mention that this could be security related (I found a mention about strict brower settings earlier but it was related to another problem).
I have uploaded my code on Github here: https://github.com/plafeber/cakephp-tutorial
I would greatly appreciate any feedback. I was under the assumption that if I create the full code set from the tutorial, given of course I run CakePHP 4.1.5 and follow the related Cake 4.x manual, that it would work. However, I already found out that I have to change the line about the use of DefaultPasswordHasher compared to what was in the code. So I can imagine the Tutorial page is not exactly as it should be.
This would be hte correct line about the use of the DefaultPasswordHasher in User.php;
//the use line
use Cake\Auth\DefaultPasswordHasher as AuthDefaultPasswordHasher;
//and the function
protected function _setPassword(string $password) : ?string
{
if (strlen($password) > 0) {
$hasher = new AuthDefaultPasswordHasher();
return $hasher->hash($password);
}
}
The solution to this was to navigate to the Cake install dir (containing the src and config folder and so on), then running the Composer call again. This apparently placed the filed in the right directories and then the error no longer appeared.

Importing the latitude and longitude into a geofield

I am using bizreview as the theme for my Drupal 7 site. I am using the Feeds module to import thousands of records that are in CSV files into the site. I need to use a geofield to store the locations.
For this I created a field 'Coordinates' in my content type, made it a geofield and set the widget type to latitude/longitude. I can add the locations manually and they do show up in the map, but I just can't import the coordinates with Feeds.
This seems to be an ongoing issue with the geofield/feeds interface (see Drupal issue here). I had the same problem but applied the patch in comment #12 from the aforementioned link which worked.
One suggestion: If the current version of geofield is not the same as the one used in the patch, or if you are running WAMP without Cygwin, I would suggest applying the patch manually by following the directions here, making sure to save a safe backup file in the process. If you haven't worked with patches before, basically all that you (or the patch command) will do for this particular case is add the following lines of code after line 143 in the ./sites/all/modules/geofield/geofield.feeds.inc file (I am working with geofield version 7.x-2.3):
foreach ($field[LANGUAGE_NONE] as $delta => $value) {
if (!empty($value['lat']) && !empty($value['lon'])) {
// Build up geom data.
$field[LANGUAGE_NONE][$delta] = geofield_compute_values($value, 'latlon');
}
}

I am getting 'ZZ' as country code when using pytz

I am using App engine, and I'm trying to get the time zone from the request.
However when on local host it always seems to return 'ZZ' as the country code which is not a country in pytz library.
This code:
country = self.request.headers['X-Appengine-Country']
logging.info(country)
tz = pytz.country_timezones(country)
produces this error:
return self.data[key.upper()]
KeyError: 'ZZ'
many thanks for your help
'ZZ' is often used to denote 'Unknown or unspecified country'
There is also a numeric version of the two letter code, calculated as 1070+30a+b, where a and b are the two letters of the code converted by A=1, B=2, etc. So AA=1101, AB=1102, BA=1131, and ZZ=1876.
I suggest that you use the correct case for the Request Header names. For e.g. X-AppEngine-Country
However, in the local development environment - I do not think the Location features will be supported i.e. you will not get the correct values. These should work only on the deployment environment. The Location is most likely provided by a Google Service that is internal to the Google Network and not exposed in the Local Development Environment.
Try to deploy your code to the live environment and check the values.

App Engine Instance ID

Is it possible to get info on what instance you're running on? I want to output just a simple identifier for which instance the code is currently running on for logging purposes.
Since there is no language tag, and seeing your profile history, I assume you are using GAE/J?
In that case, the instance ID information is embedded in one of the environment attributes that you could get via ApiProxy.getCurrentEnvironment() method. You could then extract the instance id from the resulting map using key BackendService.INSTANCE_ID_ENV_ATTRIBUTE.
Even though the key is stored in BackendService, this approach will also work for frontend instances. So in summary, the following code would fetch the instance ID for you:
String tInstanceId = ApiProxy.getCurrentEnvironment()
.getAttributes()
.get( BackendService.INSTANCE_ID_ENV_ATTRIBUTE )
.toString();
Please keep in mind that this approach is quite undocumented by Google, and might subject to change without warning in the future. But since your use case is only for logging, I think it would be sufficient for now.
With the advent of Modules, you can get the current instance id in a more elegant way:
ModulesServiceFactory.getModulesService().getCurrentInstanceId()
Even better, you should wrap the call in a try catch so that it will work correctly locally too.
Import this
import com.google.appengine.api.modules.ModulesException;
import com.google.appengine.api.modules.ModulesServiceFactory;
Then your method can run this
String instanceId = "unknown";
try{
instanceId = ModulesServiceFactory.getModulesService().getCurrentInstanceId();
} catch (ModulesException e){
instanceId = e.getMessage();
}
Without the try catch, you will get some nasty errors when running locally.
I have found this super useful for debugging when using endpoints mixed with pub-sub and other bits to try to determine why some things work differently and to determine if it is related to new instances.
Not sure about before, but today in 2021 the system environment variable GAE_INSTANCE appears to contain the instance id:
instanceId = System.getenv("GAE_INSTANCE")

AppEngine: Get current serving application version

Is there a simple way to get the current serving application version in AppEngine?
os.environ['CURRENT_VERSION_ID']
String version = SystemProperty.version.get();
String applicationVersion = SystemProperty.applicationVersion.get();
This is the syntax:
public static final SystemProperty applicationVersion
The major version number for the currently running version of the application plus a timestamp at which it was deployed. Has the key, "com.google.appengine.application.version".
See here
PS. One puzzle still remains. What does timestamp next to version means and how to read it??
EDIT: Here is the key to the mystery.
Date UploadDate = new Date(Long.parseLong(
applicationVersion.substring(applicationVersion.lastIndexOf(‌​".")+1))
/ (2 << 27) * 1000);
For Python (GAE SDK release: "1.4.2")
version_id = self.request.environ["CURRENT_VERSION_ID"].split('.')[1]
timestamp = long(version_id) / pow(2,28)
version = datetime.datetime.fromtimestamp(timestamp).strftime("%d/%m/%y %X")
See http://groups.google.com/group/google-appengine-python/browse_thread/thread/f86010e7cf3c71b4
from google.appengine.api import modules
modules.get_current_version_name()
Source: https://cloud.google.com/appengine/docs/python/modules/functions
For nodejs, I am not sure if this is documented.
process.env.GAE_VERSION
You can also access the process' environment variables:
GAE_VERSION
which is available when you deploy (gcloud app deploy) using the flag --version
For those who want an update, environment variables set for a GAE instance as of September 2020:
GAE_VERSION is the one that seems to answer the original question.
Google doc:
https://cloud.google.com/appengine/docs/standard/python3/runtime#environment_variables
The following environment variables are set by the runtime:
Environment variable Description
GAE_APPLICATION The ID of your App Engine application. This ID is prefixed with 'region code~' such as 'e~' for applications deployed in Europe.
GAE_DEPLOYMENT_ID The ID of the current deployment.
GAE_ENV The App Engine environment. Set to standard.
GAE_INSTANCE The ID of the instance on which your service is currently running.
GAE_MEMORY_MB The amount of memory available to the application process, in MB.
GAE_RUNTIME The runtime specified in your app.yaml file.
GAE_SERVICE The service name specified in your app.yaml file. If no service name is specified, it is set to default.
GAE_VERSION The current version label of your service.
GOOGLE_CLOUD_PROJECT The Cloud project ID associated with your application.
PORT The port that receives HTTP requests.
Based on my experiments today, there are two os.environ variables that you can use to get the current app version:
os.environ['GAE_VERSION']: the version name only
os.environ['CURRENT_VERSION_ID']: a unique version identifier composed of {version name}.{deployment id}, which is equivalent to os.environ['GAE_VERSION'] + '.' + os.environ['GAE_DEPLOYMENT_ID']
It appears that the so-called "deployment id" can be right-shifted 28 bits to get a timestamp in epoch seconds (as other answers already described).
For example: I deployed version "101" of my app at 2021-03-04T00:17:12Z and I'm seeing the following values:
os.environ['GAE_VERSION']: '101'
os.environ['CURRENT_VERSION_ID']: '101.433474146608888597'
os.environ['GAE_DEPLOYMENT_ID']: '433474146608888597'
You can use the following code to get the version name and timestamp from os.environ['CURRENT_VERSION_ID']:
>>> import os
>>> import datetime
>>> version_id = os.environ['CURRENT_VERSION_ID'] # example: '101.433474146608888597'
>>> name, ts = version_id.split('.')
>>> dt = datetime.datetime.utcfromtimestamp(int(ts) >> 28))
>>> dt.isoformat()
'2021-03-04T00:17:12'
Disclaimer: Most of this functionality is undocumented and the deployment ID format may be subject to change.

Resources