Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Authentication token as another option for authentication apart from api_key #13

Merged
merged 6 commits into from
Aug 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ jobs:
env:
XYZ_TOKEN: ${{ secrets.XYZ_TOKEN }}
LS_API_KEY: ${{ secrets.LS_API_KEY }}
HERE_USER_ID: ${{ secrets.HERE_USER_ID }}
HERE_CLIENT_ID: ${{ secrets.HERE_CLIENT_ID }}
HERE_ACCESS_KEY_ID: ${{ secrets.HERE_ACCESS_KEY_ID }}
HERE_ACCESS_KEY_SECRET: ${{ secrets.HERE_ACCESS_KEY_SECRET }}
HERE_TOKEN_ENDPOINT_URL: ${{ secrets.HERE_TOKEN_ENDPOINT_URL }}
run: |
pytest -v --durations=10 --cov-report=xml --cov=here_location_services tests

Expand Down
243 changes: 243 additions & 0 deletions docs/notebooks/authentication.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Authentication\n",
"\n",
"This notebook demonstrates two ways to authenticate Location services APIs.\n",
"- Using API key from [Here developer portal](https://developer.here.com/documentation/identity-access-management/dev_guide/topics/dev-apikey.html) or [Here platform](https://developer.here.com/documentation/identity-access-management/dev_guide/topics/plat-using-apikeys.html)\n",
"- Using OAuth Token from Here platform."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Authentication using API key "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from here_location_services import LS"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"copy your API key into environment variable"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"LS_API_KEY\"] = \"YOUR-API-KEY\" # replace your API key here."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"api_key = os.environ[\"LS_API_KEY\"]\n",
"\n",
"ls = LS(api_key=api_key)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# geocoding example\n",
"\n",
"address = \"Invalidenstr 116, 10115 Berlin, Germany\"\n",
"gc_response = ls.geocode(query=address)\n",
"\n",
"gc_response.response"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Authentication using OAuth token "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To authenticate using OAuth token of HERE Platform account.\n",
"\n",
"login to HERE Platform follow the below steps to get credentials:\n",
"- Go to [HERE Platform Applications and Keys](https://platform.here.com/profile/apps-and-keys) and register a new app.\n",
"- Create a key for the app and download the generated `credentials.properties` file.\n",
"\n",
"\n",
"The HERE platform generated app credentials should look similar to the example below:\n",
"```bash\n",
"here.user.id = <example_here>\n",
"here.client.id = <example_here>\n",
"here.access.key.id = <example_here>\n",
"here.access.key.secret = <example_here>\n",
"here.token.endpoint.url = <example_here>\n",
"```\n",
"To get more details on the HERE Platform account please check [this](https://developer.here.com/documentation/identity-access-management/dev_guide/topics/plat-token.html)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can provide your credentials using any of the following methods:\n",
"- Default credentials\n",
"- Environment variables\n",
"- Credentials file\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Default credentials"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Place the credentials.properties file into:\n",
" \n",
"For Linux/MacOS: $HOME/.here/credentials.properties\n",
"\n",
"For Windows: %USERPROFILE%\\.here\\credentials.properties"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# credentials will be picked up from credentials.properties file placed at default location. \n",
"from here_location_services import LS\n",
"\n",
"ls = LS()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Environment Variables"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can override default credentials by assigning values to the following environment variables:\n",
"```\n",
"HERE_USER_ID\n",
"HERE_CLIENT_ID\n",
"HERE_ACCESS_KEY_ID\n",
"HERE_ACCESS_KEY_SECRET\n",
"HERE_TOKEN_ENDPOINT_URL\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"os.environ[\"HERE_USER_ID\"] = \"replace here.user.id value here\"\n",
"os.environ[\"HERE_CLIENT_ID\"] = \"replace here.client.id value here\"\n",
"os.environ[\"HERE_ACCESS_KEY_ID\"] = \"replace here.access.key.id value here\"\n",
"os.environ[\"HERE_ACCESS_KEY_SECRET\"] = \"replace here.access.key.secret value here\"\n",
"os.environ[\"HERE_TOKEN_ENDPOINT_URL\"] = \"replace here.token.endpoint.url value here\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from here_location_services import LS\n",
"from here_location_services.platform.credentials import PlatformCredentials\n",
"\n",
"\n",
"credentials = PlatformCredentials.from_env()\n",
"\n",
"ls = LS(platfrom_credentials=credentials)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Credentials File"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can specify any credentials file as an alternative to that found in `~/.here/credentials.properties`. An error is generated if there is no file present at the path, or if the file is not properly formatted."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from here_location_services import LS\n",
"from here_location_services.platform.credentials import PlatformCredentials\n",
"\n",
"\n",
"credentials = PlatformCredentials.from_credentials_file(\"<Path to file>\")\n",
"\n",
"ls = LS(platfrom_credentials=credentials)"
]
}
],
"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.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
43 changes: 21 additions & 22 deletions here_location_services/apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import requests

from here_location_services.config.url_config import conf
from here_location_services.platform.auth import Auth


class Api:
Expand All @@ -20,26 +21,18 @@ class Api:
def __init__(
self,
api_key: Optional[str] = None,
auth: Optional[Auth] = None,
proxies: Optional[dict] = None,
country: str = "row",
):
self.credentials = dict(api_key=api_key)
self.auth = auth
self.credentials = dict(
api_key=api_key, access_token=self.auth.token if self.auth else None
)
self.proxies = proxies or urllib.request.getproxies()
self.headers: Dict[str, str] = {}
self.country = country

@property
def credential_params(self) -> dict:
"""
Return dict. with credentials info to be used as query parameters.
"""
if self.credentials["api_key"]:
return dict(apiKey=self.credentials["api_key"])
else:
raise Exception(
f"api_key: {self.credentials['api_key']} is not present in credentials."
)

def _get_url_string(self) -> str:
"""
Get url string from config based on type of country.
Expand All @@ -49,21 +42,21 @@ def _get_url_string(self) -> str:

:raises Exception: If ``api_key`` not found in credentials.
"""
if self.credentials["api_key"]:
if self.credentials["api_key"] or self.credentials["access_token"]:
url = conf[self.country]["here_api"]
return url
else:
raise Exception(
f"api_key: {self.credentials['api_key']} is not present in credentials."
)

def __add_credentials_in_params(self, params: Dict) -> Dict:
def __add_api_key_in_params(self, params: Dict) -> Dict:
"""
Add credentials in params dictionary.
Add api_key in query params dictionary.

:return: Dict.
"""
params.update(self.credential_params)
params.update({"apiKey": self.credentials["api_key"]})
return params

def get(self, url: str, params: Optional[Dict] = None, **kwargs):
Expand All @@ -75,9 +68,12 @@ def get(self, url: str, params: Optional[Dict] = None, **kwargs):
:return: :class:`requests.Response` object.
"""
q_params = params if params is not None else {}
if self.credential_params:
q_params = self.__add_credentials_in_params(q_params)
resp = requests.get(url, params=q_params, **kwargs)
if self.credentials["api_key"]:
q_params = self.__add_api_key_in_params(q_params)
elif self.credentials["access_token"]:
auth_token = {"Authorization": f"Bearer {self.credentials['access_token']}"}
self.headers.update(auth_token)
resp = requests.get(url, params=q_params, headers=self.headers, **kwargs)
return resp

def post(self, url: str, data: Dict, params: Optional[Dict] = None):
Expand All @@ -91,8 +87,11 @@ def post(self, url: str, data: Dict, params: Optional[Dict] = None):
"""
self.headers.update({"Content-Type": "application/json"})
q_params = params if params is not None else {}
if self.credential_params:
q_params = self.__add_credentials_in_params(q_params)
if self.credentials["api_key"]:
q_params = self.__add_api_key_in_params(q_params)
elif self.credentials["access_token"]:
auth_token = {"Authorization": f"Bearer {self.credentials['access_token']}"}
self.headers.update(auth_token)
resp = requests.post(
url, params=q_params, json=data, proxies=self.proxies, headers=self.headers
)
Expand Down
Loading