Skip to content

Commit

Permalink
fix: don't rely on gcloud for asset discovery (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
12rambau authored Sep 26, 2024
2 parents 5b8cbde + 05e50e8 commit 69b0416
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 3 deletions.
131 changes: 131 additions & 0 deletions example.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import ee \n",
"\n",
"ee.Authenticate()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ee.Initialize(project=\"ee-borntobealive\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from ipygee.asset import AssetManager\n",
"from ipygee.task import TaskManager\n",
"from ipygee.map import Map"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"am = AssetManager()\n",
"am.to_sidecar()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tm = TaskManager()\n",
"tm.to_sidecar()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"m = Map()\n",
"m.to_sidecar()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
}
},
"outputs": [],
"source": [
"dataset = (\n",
" ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')\n",
" .filter(ee.Filter.date('2020-07-01', '2020-07-02'))\n",
")\n",
"\n",
"visualization = {\n",
" \"bands\": ['temperature_2m'],\n",
" \"min\": 250.0,\n",
" \"max\": 320.0,\n",
" \"palette\": [\n",
" '000080', '0000d9', '4000ff', '8000ff', '0080ff', '00ffff',\n",
" '00ff80', '80ff00', 'daff00', 'ffff00', 'fff500', 'ffda00',\n",
" 'ffb000', 'ffa400', 'ff4f00', 'ff2500', 'ff0a00', 'ff00ff',\n",
" ]\n",
"}\n",
"\n",
"m.setCenter(22.2, 21.2, 0)\n",
"\n",
"m.addLayer(dataset, visualization, 'Air temperature [K] at 2m height')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
45 changes: 42 additions & 3 deletions ipygee/asset.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""The asset manager widget code and functionalities."""
from __future__ import annotations

import json
from pathlib import Path
from typing import List, Optional

import ee
import geetools # noqa
import ipyvuetify as v
import requests
import traitlets as t
from google.cloud.resourcemanager import ProjectsClient
from natsort import humansorted

from .decorator import switch
Expand Down Expand Up @@ -127,14 +128,52 @@ def __init__(self):
self.w_view.on_event("click", self.on_view)
self.w_new.on_event("click", self.on_new)

def get_projects(self) -> List:
"""Get the list of project accessible from the authenticated user."""
# recover the saved credentials of the user from the file system
credential_path = Path.home() / ".config" / "earthengine" / "credentials"
creds = json.loads(credential_path.read_text())

# get an authentication token for this very account and make requests to the Google
# REST API
url = "https://cloudresourcemanager.googleapis.com/v1/projects"
token_url = "https://oauth2.googleapis.com/token"
creds["grant_type"] = "refresh_token"
response = requests.post(token_url, data=creds)

if response.status_code == 200:
access_token = response.json().get("access_token")
else:
raise ValueError(f"Failed to retrieve access token: {response.text}")

# Define the API endpoint and headers and list all the projects available
cloud_resource_manager_url = "https://cloudresourcemanager.googleapis.com/v1/projects"
headers = {"Authorization": f"Bearer {access_token}"}
response = requests.get(cloud_resource_manager_url, headers=headers)

# Handle the response
if response.status_code == 200:
projects = [p["projectId"] for p in response.json()["projects"]]
else:
raise ValueError(f"API request failed: {response.text}")

# filter out the projects that are not compatible with GEE
url = "https://serviceusage.googleapis.com/v1/projects/{}/services/earthengine.googleapis.com"
gee_projects = []
for p in projects:
response = requests.get(url.format(p), headers=headers)
if response.status_code == 200:
gee_projects.append(p)

return gee_projects

def get_items(self) -> List[v.ListItem]:
"""Create the list of items inside a folder."""
# special case when we are at the root of everything
# because of the specific display of cloud projects we will store both the name and the id of everything as a dict
# for all other item types it will simply be the Name
if self.folder == ".":
list_items = [p.project_id for p in ProjectsClient().search_projects() if "earth-engine" in p.labels] # fmt: skip
list_items = [{"id": f"projects/{i}/assets", "name": i} for i in list_items]
list_items = [{"id": f"projects/{i}/assets", "name": i} for i in self.get_projects()]
else:
list_items = [{"id": str(i), "name": i.name} for i in ee.Asset(self.folder).iterdir()]

Expand Down

0 comments on commit 69b0416

Please sign in to comment.