From a9e1b2854bc517b64be62ec556fd70a9b9f61c2a Mon Sep 17 00:00:00 2001 From: Qiusheng Wu Date: Thu, 6 Jul 2023 09:59:08 -0400 Subject: [PATCH] Update SciPy notebook --- docs/workshops/SciPy_2023.ipynb | 30 ++-- examples/workshops/SciPy_2023.ipynb | 30 ++-- geemap/common.py | 210 +++++++++++++++------------- 3 files changed, 129 insertions(+), 141 deletions(-) diff --git a/docs/workshops/SciPy_2023.ipynb b/docs/workshops/SciPy_2023.ipynb index 96a00c406c..1c00f73d28 100644 --- a/docs/workshops/SciPy_2023.ipynb +++ b/docs/workshops/SciPy_2023.ipynb @@ -2139,9 +2139,7 @@ "metadata": {}, "outputs": [], "source": [ - "geemap.pie_chart(\n", - " 'treeloss.csv', names='NAME', values='sum', max_rows=20, height=600\n", - ")" + "geemap.pie_chart('treeloss.csv', names='NAME', values='sum', max_rows=20, height=600)" ] }, { @@ -2545,7 +2543,8 @@ "outputs": [], "source": [ "geemap.download_ee_image_tiles_parallel(\n", - " image, fishnet, out_dir='tiles', scale=1000, crs='EPSG:3857')" + " image, fishnet, out_dir='tiles', scale=1000, crs='EPSG:3857'\n", + ")" ] }, { @@ -3113,27 +3112,16 @@ "\n", "This section is optional. We might not have enough time to cover this section.\n", "\n", - "### Developing interactive Earth Engine web apps with geemap\n", + "Follow the instructions [here](https://huggingface.co/spaces/giswqs/solara-geemap) to build an interactive Earth Engine web app with [Solara](https://github.com/widgetti/solara) and geemap. You need to [sign up](https://huggingface.co/join) for a free Hugging Face account to create the web app. It is free and easy to sign up.\n", "\n", - "- Streamlit: \n", - "- Solara: \n", - "- Template: \n", + "### Exercise 7 - Building an interactive web app for visualizing land cover change\n", "\n", - "### Publish web apps on Hugging Face\n", + "After following the instructions above, you should have a web app that looks like this:\n", "\n", - "- Streamlit: \n", - "- Solara: \n", - "- Template: \n", + "![](https://i.imgur.com/uYDUPl0.png)\n", "\n", - "### Exercise 7 - Building an interactive web app for visualizing land cover change" + "The web app URL should look like this: https://giswqs-solara-geemap.hf.space/split-map." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -3152,7 +3140,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.9" } }, "nbformat": 4, diff --git a/examples/workshops/SciPy_2023.ipynb b/examples/workshops/SciPy_2023.ipynb index 96a00c406c..1c00f73d28 100644 --- a/examples/workshops/SciPy_2023.ipynb +++ b/examples/workshops/SciPy_2023.ipynb @@ -2139,9 +2139,7 @@ "metadata": {}, "outputs": [], "source": [ - "geemap.pie_chart(\n", - " 'treeloss.csv', names='NAME', values='sum', max_rows=20, height=600\n", - ")" + "geemap.pie_chart('treeloss.csv', names='NAME', values='sum', max_rows=20, height=600)" ] }, { @@ -2545,7 +2543,8 @@ "outputs": [], "source": [ "geemap.download_ee_image_tiles_parallel(\n", - " image, fishnet, out_dir='tiles', scale=1000, crs='EPSG:3857')" + " image, fishnet, out_dir='tiles', scale=1000, crs='EPSG:3857'\n", + ")" ] }, { @@ -3113,27 +3112,16 @@ "\n", "This section is optional. We might not have enough time to cover this section.\n", "\n", - "### Developing interactive Earth Engine web apps with geemap\n", + "Follow the instructions [here](https://huggingface.co/spaces/giswqs/solara-geemap) to build an interactive Earth Engine web app with [Solara](https://github.com/widgetti/solara) and geemap. You need to [sign up](https://huggingface.co/join) for a free Hugging Face account to create the web app. It is free and easy to sign up.\n", "\n", - "- Streamlit: \n", - "- Solara: \n", - "- Template: \n", + "### Exercise 7 - Building an interactive web app for visualizing land cover change\n", "\n", - "### Publish web apps on Hugging Face\n", + "After following the instructions above, you should have a web app that looks like this:\n", "\n", - "- Streamlit: \n", - "- Solara: \n", - "- Template: \n", + "![](https://i.imgur.com/uYDUPl0.png)\n", "\n", - "### Exercise 7 - Building an interactive web app for visualizing land cover change" + "The web app URL should look like this: https://giswqs-solara-geemap.hf.space/split-map." ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -3152,7 +3140,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.9" } }, "nbformat": 4, diff --git a/geemap/common.py b/geemap/common.py index 4705d7c3db..3226b27d4f 100644 --- a/geemap/common.py +++ b/geemap/common.py @@ -31,6 +31,100 @@ pass +def ee_initialize( + token_name="EARTHENGINE_TOKEN", + auth_mode="notebook", + service_account=False, + auth_args={}, + **kwargs, +): + """Authenticates Earth Engine and initialize an Earth Engine session + + Args: + token_name (str, optional): The name of the Earth Engine token. Defaults to "EARTHENGINE_TOKEN". + auth_mode (str, optional): The authentication mode, can be one of paste,notebook,gcloud,appdefault. Defaults to "notebook". + service_account (bool, optional): If True, use a service account. Defaults to False. + auth_args (dict, optional): Additional authentication parameters for aa.Authenticate(). Defaults to {}. + kwargs (dict, optional): Additional parameters for ee.Initialize(). For example, + opt_url='https://earthengine-highvolume.googleapis.com' to use the Earth Engine High-Volume platform. Defaults to {}. + """ + import httplib2 + from .__init__ import __version__ + + user_agent = f"geemap/{__version__}" + if "http_transport" not in kwargs: + kwargs["http_transport"] = httplib2.Http() + + auth_args["auth_mode"] = auth_mode + + if ee.data._credentials is None: + ee_token = os.environ.get(token_name) + if service_account: + try: + credential_file_path = os.path.expanduser( + "~/.config/earthengine/private-key.json" + ) + + if os.path.exists(credential_file_path): + with open(credential_file_path) as f: + token_dict = json.load(f) + else: + token_name = "EARTHENGINE_TOKEN" + ee_token = os.environ.get(token_name) + token_dict = json.loads(ee_token, strict=False) + service_account = token_dict["client_email"] + private_key = token_dict["private_key"] + + credentials = ee.ServiceAccountCredentials( + service_account, key_data=private_key + ) + ee.Initialize(credentials, **kwargs) + + except Exception as e: + raise Exception(e) + + else: + try: + if ee_token is not None: + credential_file_path = os.path.expanduser( + "~/.config/earthengine/credentials" + ) + if not os.path.exists(credential_file_path): + os.makedirs( + os.path.dirname(credential_file_path), exist_ok=True + ) + if ee_token.startswith("{") and ee_token.endswith( + "}" + ): # deals with token generated by new auth method (earthengine-api>=0.1.304). + token_dict = json.loads(ee_token) + with open(credential_file_path, "w") as f: + f.write(json.dumps(token_dict)) + else: + credential = ( + '{"refresh_token":"%s"}' % ee_token + ) # deals with token generated by old auth method. + with open(credential_file_path, "w") as f: + f.write(credential) + elif in_colab_shell(): + if credentials_in_drive() and (not credentials_in_colab()): + copy_credentials_to_colab() + elif not credentials_in_colab: + ee.Authenticate(**auth_args) + if is_drive_mounted() and (not credentials_in_drive()): + copy_credentials_to_drive() + else: + if is_drive_mounted(): + copy_credentials_to_drive() + + ee.Initialize(**kwargs) + + except Exception: + ee.Authenticate(**auth_args) + ee.Initialize(**kwargs) + + ee.data.setUserAgent(user_agent) + + def ee_export_image( ee_object, filename, @@ -1567,105 +1661,6 @@ def check_titiler_endpoint(titiler_endpoint=None): return titiler_endpoint -######################################## -# EE Authentication and Initialization # -######################################## - - -def ee_initialize( - token_name="EARTHENGINE_TOKEN", - auth_mode="notebook", - service_account=False, - auth_args={}, - **kwargs, -): - """Authenticates Earth Engine and initialize an Earth Engine session - - Args: - token_name (str, optional): The name of the Earth Engine token. Defaults to "EARTHENGINE_TOKEN". - auth_mode (str, optional): The authentication mode, can be one of paste,notebook,gcloud,appdefault. Defaults to "notebook". - service_account (bool, optional): If True, use a service account. Defaults to False. - auth_args (dict, optional): Additional authentication parameters for aa.Authenticate(). Defaults to {}. - kwargs (dict, optional): Additional parameters for ee.Initialize(). For example, - opt_url='https://earthengine-highvolume.googleapis.com' to use the Earth Engine High-Volume platform. Defaults to {}. - """ - import httplib2 - from .__init__ import __version__ - - user_agent = f"geemap/{__version__}" - if "http_transport" not in kwargs: - kwargs["http_transport"] = httplib2.Http() - - auth_args["auth_mode"] = auth_mode - - if ee.data._credentials is None: - ee_token = os.environ.get(token_name) - if service_account: - try: - credential_file_path = os.path.expanduser( - "~/.config/earthengine/private-key.json" - ) - - if os.path.exists(credential_file_path): - with open(credential_file_path) as f: - token_dict = json.load(f) - else: - token_name = "EARTHENGINE_TOKEN" - ee_token = os.environ.get(token_name) - token_dict = json.loads(ee_token, strict=False) - service_account = token_dict["client_email"] - private_key = token_dict["private_key"] - - credentials = ee.ServiceAccountCredentials( - service_account, key_data=private_key - ) - ee.Initialize(credentials, **kwargs) - - except Exception as e: - raise Exception(e) - - else: - try: - if ee_token is not None: - credential_file_path = os.path.expanduser( - "~/.config/earthengine/credentials" - ) - if not os.path.exists(credential_file_path): - os.makedirs( - os.path.dirname(credential_file_path), exist_ok=True - ) - if ee_token.startswith("{") and ee_token.endswith( - "}" - ): # deals with token generated by new auth method (earthengine-api>=0.1.304). - token_dict = json.loads(ee_token) - with open(credential_file_path, "w") as f: - f.write(json.dumps(token_dict)) - else: - credential = ( - '{"refresh_token":"%s"}' % ee_token - ) # deals with token generated by old auth method. - with open(credential_file_path, "w") as f: - f.write(credential) - elif in_colab_shell(): - if credentials_in_drive() and (not credentials_in_colab()): - copy_credentials_to_colab() - elif not credentials_in_colab: - ee.Authenticate(**auth_args) - if is_drive_mounted() and (not credentials_in_drive()): - copy_credentials_to_drive() - else: - if is_drive_mounted(): - copy_credentials_to_drive() - - ee.Initialize(**kwargs) - - except Exception: - ee.Authenticate(**auth_args) - ee.Initialize(**kwargs) - - ee.data.setUserAgent(user_agent) - - def set_proxy(port=1080, ip="http://127.0.0.1", timeout=300): """Sets proxy if needed. This is only needed for countries where Google services are not available. @@ -15313,3 +15308,20 @@ def check_basemap(basemap): return basemap else: return basemap + + +def get_ee_token(): + """Get Earth Engine token. + + Returns: + dict: The Earth Engine token. + """ + credential_file_path = os.path.expanduser("~/.config/earthengine/credentials") + + if os.path.exists(credential_file_path): + with open(credential_file_path, "r") as f: + credentials = json.load(f) + return credentials + else: + print("Earth Engine credentials not found. Please run ee.Authenticate()") + return None