From 364a723fae825be779feacc41c049897ece97ec1 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 11:49:52 -0800 Subject: [PATCH 01/12] Pro 1.0 release tweaks * Update readme to use code fences with implicit language * Remove circle.tml as I don't use it * Add deploy process to makefile Signed-off-by: David Aronsohn --- Makefile | 7 ++- README.markdown | 150 +++++++++++++++++++++++++++--------------------- circle.yml | 6 -- 3 files changed, 91 insertions(+), 72 deletions(-) delete mode 100644 circle.yml diff --git a/Makefile b/Makefile index 38639fad..20cfebb5 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,12 @@ env/bin/activate: requirements.txt dnsimple.egg-info/SOURCES.txt: env ./env/bin/python setup.py develop - + setup: dnsimple.egg-info/SOURCES.txt +deploy: + python setup.py sdist + python setup.py bdist_wheel --universal + twine upload dist/* + .PHONY: test diff --git a/README.markdown b/README.markdown index f3e2ee79..3ef11bf3 100644 --- a/README.markdown +++ b/README.markdown @@ -3,58 +3,65 @@ Python DNSimple ## Introduction -This is a client for the DNSimple REST API. It currently allows you to fetch -existing domain info, as well as register new domains and manage domain -records. +This is a client for the DNSimple REST API. It currently allows you to fetch existing domain info, as well as register new domains and manage domain records. `dnsimple-python` works for both python 2 & 3. ### Getting started -You'll need the `json` module that is included with python version 2.6 and -later, or the `simplejson` module if you are using an earlier version. +You'll need the `json` module that is included with python version 2.6 and later, or the `simplejson` module if you are using an earlier version. `dnsimple-python` also depends on the `requests` library. Import the module: - from dnsimple import DNSimple +```python +from dnsimple import DNSimple +``` You can provide your DNSimple credentials in one of two ways: 1. Provide username/password or email/api\_token credentials programmatically: +```python +# Use username/password authentication: HTTP Basic +dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD) - # Use username/password authentication: HTTP Basic - dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD) +# Use email/api_token credentials +dns = DNSimple(api_token=YOUR_API_TOKEN) - # Use email/api_token credentials - dns = DNSimple(api_token=YOUR_API_TOKEN) +# If you have many accounts you can provide account_id (661 is an example) +# You can find your account id in url (https://sandbox.dnsimple.com/a/661/account) +dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD, account_id=661) +``` - # If you have many accounts you can provide account_id (661 is an example) - # You can find your account id in url (https://sandbox.dnsimple.com/a/661/account) - dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD, account_id=661) +1. Store you username/password or email/api\_token credentials in a file called `.dnsimple` in the current directory with the following data: -2. Store you username/password or email/api\_token credentials in a file called -`.dnsimple` in the current directory with the following data: +```toml +[DNSimple] +username: email@domain.com +password: yourpassword +``` - [DNSimple] - username: email@domain.com - password: yourpassword +Or: - Or: +```toml +[DNSimple] +api_token: yourapitoken +``` - [DNSimple] - api_token: yourapitoken +Or (assuming `$DNSIMPLE_EMAIL` and `$DNSIMPLE_TOKEN` are environment variables): - Or (assuming `$DNSIMPLE_EMAIL` and `$DNSIMPLE_TOKEN` are environment variables): +```toml +[DNSimple] +email: %(DNSIMPLE_EMAIL)s +api_token: %(DNSIMPLE_TOKEN)s +``` - [DNSimple] - email: %(DNSIMPLE_EMAIL)s - api_token: %(DNSIMPLE_TOKEN)s +You then need not provide any credentials when constructing `DNSimple`: - You then need not provide any credentials when constructing `DNSimple`: - - dns = DNSimple() +```python +dns = DNSimple() +``` ## Domain Operations @@ -62,66 +69,78 @@ You can provide your DNSimple credentials in one of two ways: Just run: - domains = dns.domains() +```python +domains = dns.domains() +``` Results appear as a Python dict: - {'domain': {'created_at': '2010-10-14T09:45:32Z', - 'expires_at': '10/14/2011 5:45:00 AM', - 'id': 999, - 'last_enom_order_id': None, - 'name': 'yourdomain.com', - 'name_server_status': 'active', - 'registrant_id': 99, - 'registration_status': 'registered', - 'updated_at': '2010-10-14T10:00:14Z', - 'user_id': 99}}, - {'domain': {'created_at': '2010-10-15T16:02:34Z', - 'expires_at': '10/15/2011 12:02:00 PM', - 'id': 999, - 'last_enom_order_id': None, - 'name': 'anotherdomain.com', - 'name_server_status': 'active', - 'registrant_id': 99, - 'registration_status': 'registered', - 'updated_at': '2010-10-15T16:30:16Z', - 'user_id': 99}}] +```python +{'domain': {'created_at': '2010-10-14T09:45:32Z', + 'expires_at': '10/14/2011 5:45:00 AM', + 'id': 999, + 'last_enom_order_id': None, + 'name': 'yourdomain.com', + 'name_server_status': 'active', + 'registrant_id': 99, + 'registration_status': 'registered', + 'updated_at': '2010-10-14T10:00:14Z', + 'user_id': 99}}, +{'domain': {'created_at': '2010-10-15T16:02:34Z', + 'expires_at': '10/15/2011 12:02:00 PM', + 'id': 999, + 'last_enom_order_id': None, + 'name': 'anotherdomain.com', + 'name_server_status': 'active', + 'registrant_id': 99, + 'registration_status': 'registered', + 'updated_at': '2010-10-15T16:30:16Z', + 'user_id': 99}}] +``` ### Get details for a specific domain - dns.domain('mikemaccana.com') +```python +dns.domain('mikemaccana.com') +``` Results are the same as `domains()` above, but only show the domain specified. ### Check whether a domain is available - dns.check('google.com') +```python +dns.check('google.com') - # Hmm, looks like I'm too late to get that one... - {u'currency': u'USD', - u'currency_symbol': u'$', - u'minimum_number_of_years': 1, - u'name': u'google.com', - u'price': u'14.00', - u'status': u'unavailable'} +# Hmm, looks like I'm too late to get that one... +{u'currency': u'USD', +u'currency_symbol': u'$', +u'minimum_number_of_years': 1, +u'name': u'google.com', +u'price': u'14.00', +u'status': u'unavailable'} +``` ### Register a new domain - dns.register('newdomain.com') +```python +dns.register('newdomain.com') +``` -This will register 'newdomain.com', automatically picking the registrant\_id -from your first domain. To specify a particularly `registrant_id`, just run: +This will register 'newdomain.com', automatically picking the registrant\_id from your first domain. To specify a particularly `registrant_id`, just run: - dns.register('newdomain.com', 99) +```python +dns.register('newdomain.com', 99) +``` -Responses will be in a dictionary describing the newly created domain, same as -the `domain()` call above. +Responses will be in a dictionary describing the newly created domain, same as the `domain()` call above. ### Delete a domain Careful with this one! - dns.delete('domain-to-die.com') +```python +dns.delete('domain-to-die.com') +``` ## Record operations @@ -149,3 +168,4 @@ Licensed under the [MIT license](http://www.opensource.org/licenses/mit-license. ## Authors * Original Author [Mike MacCana](https://github.com/mikemaccana/) +* APIv2 Support [Kirill Motkov](https://github.com/lcd1232) diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 90424aa8..00000000 --- a/circle.yml +++ /dev/null @@ -1,6 +0,0 @@ -machine: - python: - version: 2.7.11 -test: - override: - - make ci From ff8a88f2dc1ace16bdc4e1047ffcb6570c2e8dcd Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 11:57:32 -0800 Subject: [PATCH 02/12] Rename, also not toml Signed-off-by: David Aronsohn --- README.markdown => README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename README.markdown => README.md (99%) diff --git a/README.markdown b/README.md similarity index 99% rename from README.markdown rename to README.md index 3ef11bf3..a913fafd 100644 --- a/README.markdown +++ b/README.md @@ -36,7 +36,7 @@ dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD, account_id=661) 1. Store you username/password or email/api\_token credentials in a file called `.dnsimple` in the current directory with the following data: -```toml +``` [DNSimple] username: email@domain.com password: yourpassword @@ -44,14 +44,14 @@ password: yourpassword Or: -```toml +``` [DNSimple] api_token: yourapitoken ``` Or (assuming `$DNSIMPLE_EMAIL` and `$DNSIMPLE_TOKEN` are environment variables): -```toml +``` [DNSimple] email: %(DNSIMPLE_EMAIL)s api_token: %(DNSIMPLE_TOKEN)s From ba3c1806ac99e9f7a9f500cff57bb03053c689d4 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:04:35 -0800 Subject: [PATCH 03/12] clean up sections add url links add APIv2 note Signed-off-by: David Aronsohn --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a913fafd..f0836591 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,12 @@ Python DNSimple ## Introduction -This is a client for the DNSimple REST API. It currently allows you to fetch existing domain info, as well as register new domains and manage domain records. +This is a client for the [DNSimple REST API](https://developer.dnsimple.com/). It currently allows you to fetch existing domain info, as well as register new domains and manage domain records. `dnsimple-python` works for both python 2 & 3. +**Note:** As of 1.0.0 this now uses [DNSimple's APIv2](https://blog.dnsimple.com/2016/12/api-v2-stable/). This has some incompatibilities with APIv1, including auth changes. Please test for breakages before use. + ### Getting started You'll need the `json` module that is included with python version 2.6 and later, or the `simplejson` module if you are using an earlier version. @@ -21,7 +23,8 @@ from dnsimple import DNSimple You can provide your DNSimple credentials in one of two ways: -1. Provide username/password or email/api\_token credentials programmatically: +#### Provide username/password or email/api\_token credentials programmatically: + ```python # Use username/password authentication: HTTP Basic dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD) @@ -34,7 +37,7 @@ dns = DNSimple(api_token=YOUR_API_TOKEN) dns = DNSimple(username=YOUR_USERNAME, password=YOUR_PASSWORD, account_id=661) ``` -1. Store you username/password or email/api\_token credentials in a file called `.dnsimple` in the current directory with the following data: +##### Store you username/password or email/api\_token credentials in a file called `.dnsimple` in the current directory with the following data: ``` [DNSimple] From 0a356056b4b71652e2dc181637fabcb42eb8b27f Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:25:50 -0800 Subject: [PATCH 04/12] Reset makefile to make testing simpler for all Signed-off-by: David Aronsohn --- Makefile | 11 +++++------ setup.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 20cfebb5..f42d66d7 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,7 @@ -.DEFAULT_GOAL := setup - -ci: - py.test tests +DEFAULT_GOAL := setup test: setup + test -f tests/.env || { echo "Set up your env file before running tests"; exit 1; } ./env/bin/py.test tests env: env/bin/activate @@ -17,9 +15,10 @@ dnsimple.egg-info/SOURCES.txt: env setup: dnsimple.egg-info/SOURCES.txt +ci: test + py.test tests + deploy: python setup.py sdist python setup.py bdist_wheel --universal twine upload dist/* - -.PHONY: test diff --git a/setup.py b/setup.py index 8a04c084..25e34e8c 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ from dnsimple import dnsimple -with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.markdown'), 'r') as readme_file: +with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md'), 'r') as readme_file: readme = readme_file.read() setup( From 84c72ba6654f73f68d0617fc73c0303eab4d30e2 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:31:40 -0800 Subject: [PATCH 05/12] Fix makefile Signed-off-by: David Aronsohn --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f42d66d7..01bf6465 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -DEFAULT_GOAL := setup +.DEFAULT_GOAL := setup test: setup test -f tests/.env || { echo "Set up your env file before running tests"; exit 1; } From f43ca64d7a8f8a11e189217727ae76e18a3caaa8 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:41:56 -0800 Subject: [PATCH 06/12] add phony Signed-off-by: David Aronsohn --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 01bf6465..373247b7 100644 --- a/Makefile +++ b/Makefile @@ -22,3 +22,5 @@ deploy: python setup.py sdist python setup.py bdist_wheel --universal twine upload dist/* + +.PHONY: test From 5017ba165d13f0cf8c1e9d1ab2558ea20bb71996 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:47:02 -0800 Subject: [PATCH 07/12] Clean before distributing, also no wheel Signed-off-by: David Aronsohn --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 373247b7..c14d819c 100644 --- a/Makefile +++ b/Makefile @@ -19,8 +19,8 @@ ci: test py.test tests deploy: + rm dist/* python setup.py sdist - python setup.py bdist_wheel --universal twine upload dist/* .PHONY: test From 64f7302015573cafe5aa5b4040fb8e44d129fc78 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 12:59:17 -0800 Subject: [PATCH 08/12] Move ci tests to makefile Signed-off-by: David Aronsohn --- .travis.yml | 4 ++-- Makefile | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4bfb06a7..03dff459 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,6 @@ python: - "3.5" - "3.6" install: - - pip install -r requirements.txt + - make ci-setup script: - - py.test tests + - make ci-test diff --git a/Makefile b/Makefile index c14d819c..c0cd0b21 100644 --- a/Makefile +++ b/Makefile @@ -7,15 +7,18 @@ test: setup env: env/bin/activate env/bin/activate: requirements.txt - test -d env || virtualenv env; \ - ./env/bin/pip install -r requirements.txt --upgrade; + test -d env || virtualenv env + ./env/bin/pip install -r requirements.txt --upgrade dnsimple.egg-info/SOURCES.txt: env ./env/bin/python setup.py develop setup: dnsimple.egg-info/SOURCES.txt -ci: test +ci-setup: + pip install -r requirements.txt --upgrade + +ci-test: py.test tests deploy: From 9f3768795560d930731de5073dfca6f087132529 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 13:01:30 -0800 Subject: [PATCH 09/12] Add space4s to trigger guild --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 03dff459..6a7e09bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: python + python: - "2.7" - "3.4" - "3.5" - "3.6" + install: - make ci-setup + script: - make ci-test From 60bbd1e4e459c7a76ff79c44c6933d34bff06a62 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 14:13:12 -0800 Subject: [PATCH 10/12] Remove no longer needed test --- tests/test_auth.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tests/test_auth.py b/tests/test_auth.py index c07e1d86..5f05f981 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -67,22 +67,3 @@ def test_basic_authentication_from_credentials_file_raises_no_exception(self, cr client = DNSimple(sandbox = True) client.domains() - - @pytest.mark.skip(reason='APIv2 does not support auth by domain token') - def test_domain_token_auth(self, client): - domain_name = 'dnsimple-domain-token.test' - - domain = client.add_domain(domain_name) - assert domain - - token_client = DNSimple(domain_token = domain['domain']['token'], sandbox = True) - - with pytest.raises(DNSimpleException) as exception: - token_client.domains() - - assert 'Authentication failed' in str(exception.value) - assert token_client.domain(domain_name)['domain']['name'] == domain_name - - client.delete(domain_name) - - assert len(client.domains()) == 0 From 4b9dffa5414e90ddecf8cbc19c9623ee0a701020 Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 15:17:44 -0800 Subject: [PATCH 11/12] Simplify makefile Signed-off-by: David Aronsohn --- .gitignore | 1 + Makefile | 16 ++++------------ 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 12075ea2..a4471c06 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ target/ ### Project Specific ### .dnsimple .env +env diff --git a/Makefile b/Makefile index c0cd0b21..c40d2fe5 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,11 @@ -.DEFAULT_GOAL := setup - -test: setup - test -f tests/.env || { echo "Set up your env file before running tests"; exit 1; } - ./env/bin/py.test tests - -env: env/bin/activate - -env/bin/activate: requirements.txt +setup: test -d env || virtualenv env ./env/bin/pip install -r requirements.txt --upgrade - -dnsimple.egg-info/SOURCES.txt: env ./env/bin/python setup.py develop -setup: dnsimple.egg-info/SOURCES.txt +test: setup + test -f tests/.env || { echo "Set up your env file before running tests"; exit 1; } + ./env/bin/py.test tests ci-setup: pip install -r requirements.txt --upgrade From b5c41bb0043957322c353d319d680a0197f8074b Mon Sep 17 00:00:00 2001 From: David Aronsohn Date: Wed, 21 Feb 2018 15:22:07 -0800 Subject: [PATCH 12/12] Use exist Signed-off-by: David Aronsohn --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c40d2fe5..a0f6eb28 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ setup: - test -d env || virtualenv env + test -e env || virtualenv env ./env/bin/pip install -r requirements.txt --upgrade ./env/bin/python setup.py develop