Skip to content

Commit

Permalink
DAS-1966 - Add helper function to retrieve EDL Bearer token.
Browse files Browse the repository at this point in the history
  • Loading branch information
owenlittlejohns committed Sep 26, 2023
1 parent 1cfa247 commit 68778d0
Showing 1 changed file with 114 additions and 10 deletions.
124 changes: 114 additions & 10 deletions docs/how_to_generate_umm_var_via_cmr_graphql.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"source": [
"# How to generate UMM-Var records via the CMR GraphQL API\n",
"\n",
"As of v2.0.0, `earthdata-varinfo` can generate and publish UMM-Var records to CMR. Functionality to generate and return UMM-Var record JSON has been embedded within the [CMR GraphQL specification](https://graphql.earthdata.nasa.gov/api). This notebook will provide an example of how to programmatically request UMM-Var records in JSON format from the CMR GraphQL API.\n",
"As of v2.0.0, `earthdata-varinfo` can generate and publish UMM-Var records to Earthdata Common Metadata Repository (CMR). Functionality to generate and return UMM-Var record JSON has been embedded within the [CMR GraphQL specification](https://graphql.earthdata.nasa.gov/api). This notebook will provide an example of how to programmatically request UMM-Var records in JSON format from the CMR GraphQL API.\n",
"\n",
"*Note: This feature of the CMR GraphQL API is currently under development and not deployed as of 2023-09-23.*\n",
"\n",
Expand All @@ -33,6 +33,115 @@
"import requests"
]
},
{
"cell_type": "markdown",
"id": "ef02d4a1",
"metadata": {},
"source": [
"## Set the environment being used:\n",
"\n",
"This notebook can be used against any environment in which the `generateVarableDrafts` attribute is available in the CMR-GraphQL interface. The `environment_name` variable in the cell below should be set to one of the following values:\n",
"\n",
"* `sit`\n",
"* `uat`\n",
"* `production`\n",
"\n",
"The `environment_name` variable is used both to identify the CMR-GraphQL URL against which the query should be performed, and to retrieve a valid Earthdata Login (EDL) Bearer token."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "02278815",
"metadata": {},
"outputs": [],
"source": [
"environment_name = 'uat'"
]
},
{
"cell_type": "markdown",
"id": "11d0b171",
"metadata": {},
"source": [
"## Retrieve a token for authorization:\n",
"\n",
"The CMR GraphQL API supports the authentication methods that can be used with the CMR. Currently, these include:\n",
"\n",
"### NASA LaunchPad tokens:\n",
"\n",
"[NASA LaunchPad tokens](https://wiki.earthdata.nasa.gov/display/CMR/Launchpad+Authentication+User%27s+Guide) do not specify an authentication scheme in the `Authorization` header:\n",
"\n",
"```\n",
"Authorization: <LaunchPad-token>\n",
"```\n",
"\n",
"LaunchPad tokens can currently be used for both CMR search and ingest.\n",
"\n",
"### EDL bearer tokens:\n",
"\n",
"The `Authorization` header for these tokens has the following format, where the \"Bearer\" authentication scheme is specified before the token:\n",
"\n",
"```\n",
"Authorization: Bearer <EDL-bearer-token>\n",
"```\n",
"\n",
"EDL Bearer tokens are currently meant to be used only when searching for records in the CMR.\n",
"\n",
"There are several ways to retrieve an EDL Bearer token:\n",
"\n",
"* Using the `https://urs.earthdata.nasa.gov/api/users/tokens` endpoint to retrieve an existing token.\n",
"* Using the `https://urs.earthdata.nasa.gov/api/users/token` endpoint to generate a new token.\n",
"* Using the [Earthdata Login](https://urs.earthdata.nasa.gov) GUI to generate and/or copy a token into a local text file or string variable.\n",
"\n",
"This notebook will use an EDL Bearer token, with the cell below defines a helper function that will be used later in the notebook to retrieve one. This function assumes that there is a `.netrc` file on the local machine, which will be used to authenticate with EDL.\n",
"\n",
"The function first uses the `/api/users/tokens` endpoint to retrieve the first existing token for a user. If there is no existing token, the `/api/users/token` endpoint is used to generate a new one."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b65f8f16",
"metadata": {},
"outputs": [],
"source": [
"urs_urls = {\n",
" 'sit': 'https://sit.urs.earthdata.nasa.gov',\n",
" 'uat': 'https://uat.urs.earthdata.nasa.gov',\n",
" 'production': 'https://urs.earthdata.nasa.gov'\n",
"}\n",
"\n",
"\n",
"def get_edl_token(environment_name: str) -> str:\n",
" \"\"\" Retrieve an EDL token for use in requests to CMR graph. If\n",
" the user identified by a local .netrc file does not have a\n",
" token then a new one will be generated.\n",
"\n",
" \"\"\"\n",
" urs_url = urs_urls.get(environment_name)\n",
"\n",
" existing_tokens_response = requests.get(\n",
" f'{urs_url}/api/users/tokens',\n",
" headers={'Content-type': 'application/json'}\n",
" )\n",
" existing_tokens_response.raise_for_status()\n",
" existing_tokens_json = existing_tokens_response.json()\n",
"\n",
" if len(existing_tokens_json) == 0:\n",
" new_token_response = requests.post(\n",
" f'{urs_url}/api/users/token',\n",
" headers={'Content-type': 'application/json'}\n",
" )\n",
" new_token_response.raise_for_status()\n",
" new_token_json = new_token_response.json()\n",
" edl_token = new_token_json['access_token']\n",
" else:\n",
" edl_token = existing_tokens_json[0]['access_token']\n",
"\n",
" return edl_token"
]
},
{
"cell_type": "markdown",
"id": "b52955a2-51a9-4269-9b55-f116e1268a43",
Expand All @@ -57,7 +166,7 @@
" 'production': 'https://graphql.earthdata.nasa.gov/api'\n",
"}\n",
"\n",
"graphql_url = graphql_environments['uat']"
"graphql_url = graphql_environments[environment_name]"
]
},
{
Expand Down Expand Up @@ -167,10 +276,10 @@
"\n",
"The HTTP request made in this notebook requires two headers:\n",
"\n",
"* `Authorization` - this will include an [Earthdata Login](https://urs.earthdata.nasa.gov/) (EDL) Bearer token.\n",
"* `Authorization` - this will include an [Earthdata Login](https://urs.earthdata.nasa.gov/) (EDL) Bearer token or a NASA LaunchPad token. (There are more details above on these token types)\n",
"* `Content-Type` - this header tells the HTTP request the media type of the body of the request. In this case the request contains JSON, as defined in the payload above.\n",
"\n",
"This notebook assumes that there is a file in the same directory as the notebook called `edl_token.txt`, and that it contains a valid EDL Bearer token for the environment being accessed (as defined by `graphql_url`)."
"This notebook will retrieve an EDL Bearer token for authentication with CMR. This requires a `.netrc` to be present on the local machine, and for that file to contain credentials for the necessary EDL environment (SIT, UAT, production)."
]
},
{
Expand All @@ -180,13 +289,8 @@
"metadata": {},
"outputs": [],
"source": [
"# Read the authorization token from a file\n",
"with open('edl_token.txt', 'r') as file_handler:\n",
" edl_token = file_handler.read().strip()\n",
"\n",
"# Create headers, including the EDL Bearer token\n",
"headers = {\n",
" 'Authorization': f'Bearer {edl_token}',\n",
" 'Authorization': f'Bearer {get_edl_token(environment_name)}',\n",
" 'Content-Type': 'application/json',\n",
"}"
]
Expand Down

0 comments on commit 68778d0

Please sign in to comment.