Skip to content

Commit

Permalink
Merge branch 'gh_62' into 'support_202203'
Browse files Browse the repository at this point in the history
Support User & Org API keys #62

See merge request gh/peeringdb/peeringdb-py!9
  • Loading branch information
vegu committed Mar 31, 2022
2 parents 95c50d0 + 7914dba commit 4573528
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
.coverage
.pytest_cache/
.tox
*.sqlite3
coverage.xml
dist/
site/
venv/
17 changes: 17 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ If you provide authentication in your config file, it will include contacts much
<!-- After everything is configured, check your setup and install any new dependencies with: -->
<!-- peeringdb depcheck -->

## Authentication
To sync with peeringdb API servers, you need to provide authentication. Basic authentication is supported, but you can also use your API keys. To sync with PeeringDB, you can add the following config:


sync:
api_key: 'YOUR_API_KEY_HERE'
user: 'username'
password: 'password'
only: []
strip_tz: 1
timeout: 0
url: https://peeringdb.com/api

This will also be prompted during the configuration wizard.

Please take note that only one authentication method is supported, either basic or API key.

## Tips
### MySQL
You need to use utf8 and a utf8 collation before doing the initial sync.
Expand Down
41 changes: 38 additions & 3 deletions src/peeringdb/_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Fetcher(RestClient):

def __init__(self, **kwargs):
# self.return_error = True
self.api_key = kwargs.get("api_key", "")
super().__init__(**kwargs)

def _req(self, func):
Expand Down Expand Up @@ -96,6 +97,7 @@ def _request(self, typ, id=0, method="GET", params=None, data=None, url=None):
user_agent = "PeeringDB/{} {}/{}".format(
peeringdb.__version__, backend, backend_version
)

headers = {
"Accept": "application/json",
"User-Agent": user_agent,
Expand All @@ -110,6 +112,39 @@ def _request(self, typ, id=0, method="GET", params=None, data=None, url=None):
else:
url = "{}/{}".format(self.url, typ)

return requests.request(
method, url, params=params, data=data, auth=auth, headers=headers
)
if auth and self.api_key:
raise ValueError("Cannot use both API key and basic auth")

if auth:
response = requests.request(
method, url, params=params, data=data, auth=auth, headers=headers
)

if response.status_code != 200:
raise ValueError(
"Authentication failed: {}".format(
response.json().get("meta", {}).get("error", "")
)
)
return response

if self.api_key:
headers["Authorization"] = "Api-Key {}".format(self.api_key)
response = requests.request(
method, url, params=params, data=data, headers=headers
)
if response.status_code != 200:
raise ValueError(
"Authentication failed: {}".format(
response.json().get("meta", {}).get("error", "")
)
)
return response


if not auth or not self.api_key:
response = requests.request(
method, url, params=params, data=data, headers=headers
)

return response
1 change: 1 addition & 0 deletions src/peeringdb/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SyncSchema(_schema.Schema):
strip_tz = _schema.Int("strip_tz", default=1) # FIXME no boolean?
only = _schema.List("only", item=_schema.Str(), default=[])
timeout = _schema.Int("timeout", default=0)
api_key = _schema.Str("api_key", blank=True, default="")

class OrmSchema(_schema.Schema):
class OrmDbSchema(_schema.Schema):
Expand Down
1 change: 1 addition & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def test_schema_migration():
}
new_data = {
"sync": {
"api_key": "",
"url": "https://test.peeringdb.com/api",
"user": "dude",
"password": "12345",
Expand Down
14 changes: 14 additions & 0 deletions tests/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ def test_dry_run(client_empty):
client.get(Network, FIRST_NET)


@pytest.mark.sync
def test_auth(client_empty):

with pytest.raises(ValueError):
config = helper.CONFIG
config["sync"]["user"] = "test"
config["sync"]["password"] = "test"
config["sync"]["api_key"] = "test"
client = Client(config, dry_run=True)
rs = all_resources()
client.update_all(rs)
client.get(Network, FIRST_NET)


# TODO:

# data integrity (needs mocking?)
Expand Down

0 comments on commit 4573528

Please sign in to comment.