Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/third_party/endpoints/_endpointscfg_setup.py b/third_party/endpoints/_endpointscfg_setup.py
new file mode 100644
index 0000000..a286056
--- /dev/null
+++ b/third_party/endpoints/_endpointscfg_setup.py
@@ -0,0 +1,107 @@
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Module for setting up App Engine library paths.
+
+This module searches for the root of the App Engine Python SDK or Google Cloud
+SDK and computes a list of library paths and adds them to sys.path. This is
+necessary for two reasons:
+
+1. The endpointscfg tool imports user code and therefore must be able to
+   import modules used in the app.
+2. As a consequence of the first item, we must call an App Engine method to
+   set up service stubs in case an app's initialization code utilizes an App
+   Engine service. For example, there exists an App Engine version of pytz
+   which uses memcache and users may use it at the global level because it
+   seems to be declarative.
+"""
+import logging
+import os
+import sys
+
+_PYTHON_EXTENSIONS_WARNING = """
+Found Cloud SDK, but App Engine Python Extensions are not
+installed. If you encounter errors, please run:
+  $ gcloud components install app-engine-python
+""".strip()
+
+
+_IMPORT_ERROR_WARNING = """
+Could not import App Engine Python libraries. If you encounter
+errors, please make sure that the SDK binary path is in your PATH environment
+variable or that the ENDPOINTS_GAE_SDK variable points to a valid SDK root.
+""".strip()
+
+
+_NOT_FOUND_WARNING = """
+Could not find either the Cloud SDK or the App Engine Python SDK.
+If you encounter errors, please make sure that the SDK binary path is in your
+PATH environment variable or that the ENDPOINTS_GAE_SDK variable points to a
+valid SDK root.""".strip()
+
+
+_NO_FIX_SYS_PATH_WARNING = """
+Could not find the fix_sys_path() function in dev_appserver.
+If you encounter errors, please make sure that your Google App Engine SDK is
+up-to-date.""".strip()
+
+
+def _FindSdkPath():
+  environ_sdk = os.environ.get('ENDPOINTS_GAE_SDK')
+  if environ_sdk:
+    maybe_cloud_sdk = os.path.join(environ_sdk, 'platform', 'google_appengine')
+    if os.path.exists(maybe_cloud_sdk):
+      return maybe_cloud_sdk
+    return environ_sdk
+
+  for path in os.environ['PATH'].split(os.pathsep):
+    if os.path.exists(os.path.join(path, 'dev_appserver.py')):
+      if (path.endswith('bin') and
+          os.path.exists(os.path.join(path, 'gcloud'))):
+        # Cloud SDK ships with dev_appserver.py in a bin directory. In the
+        # root directory, we can find the Python SDK in
+        # platform/google_appengine provided that it's installed.
+        sdk_path = os.path.join(os.path.dirname(path),
+                                'platform',
+                                'google_appengine')
+        if not os.path.exists(sdk_path):
+          logging.warning(_PYTHON_EXTENSIONS_WARNING)
+        return sdk_path
+      # App Engine SDK ships withd dev_appserver.py in the root directory.
+      return path
+
+
+def _SetupPaths():
+  """Sets up the sys.path with special directories for endpointscfg.py."""
+  sdk_path = _FindSdkPath()
+  if sdk_path:
+    sys.path.append(sdk_path)
+    try:
+      import dev_appserver  # pylint: disable=g-import-not-at-top
+      if hasattr(dev_appserver, 'fix_sys_path'):
+        dev_appserver.fix_sys_path()
+      else:
+        logging.warning(_NO_FIX_SYS_PATH_WARNING)
+    except ImportError:
+      logging.warning(_IMPORT_ERROR_WARNING)
+  else:
+    logging.warning(_NOT_FOUND_WARNING)
+
+  # Add the path above this directory, so we can import the endpoints package
+  # from the user's app code (rather than from another, possibly outdated SDK).
+  # pylint: disable=g-import-not-at-top
+  from google.appengine.ext import vendor
+  vendor.add(os.path.dirname(os.path.dirname(__file__)))
+
+
+_SetupPaths()