Skip to content

Commit

Permalink
final changes for release
Browse files Browse the repository at this point in the history
  • Loading branch information
aschleg committed Nov 8, 2024
1 parent 1ba0803 commit ff3d88e
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 129 deletions.
43 changes: 0 additions & 43 deletions .circleci/config.yml

This file was deleted.

16 changes: 10 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@

Changelog and version changes made with each release.

## Version 2.3.2
## Version 2.4.0

* Implemented rate-limiting for API calls that could potentially exceed the quotas
set by Petfinder (50 calls/second, 1,000/day). An exponential backoff strategy is employed when rates exceed
the given limits and tries ten more times before giving up and returning the collected results.
* Access token that is generated on first initialization of Petfinder is now refreshed automatically
after expiring.

* Access token that is generated on first initialization of Petfinder should now refresh automatically
after expiring.
* Removed the `max_page_warning` that would be displayed when there were fewer total pages
in the Petfinder API results to those requested in the `pages` parameter.
* A `response` key has been added to the returned animal or organization object. If an ID isn't found,
the `response` value will be 404.
* Type annotations have been added to the `Petfinder` methods.

## Version 2.3.1

Expand All @@ -25,7 +29,7 @@ Changelog and version changes made with each release.
- `special_needs`: Filters results by animals that have special needs
* Search filters that can take multiple values in the `animals()` function,
including `age`, `gender`, `status`, `animal_type`, `size`, and `coat`, should
now correctly accept both comma-delimited strings, such as `age='baby,'young'`
now correctly accept both comma-delimited strings, such as `age='baby,young'`
and lists or tuples.
* The required version for `pandas` has been updated to at least version `1.0.0`

Expand All @@ -37,7 +41,7 @@ Very small maintenance patch to update several `setup.py` settings. There is no

* Support for Python 3.5 has been discontinued.
* The `animals()` method has been updated to include new parameters provided by Petfinder's `animal`
endpoint. This parameters include:
endpoint. These parameters include:
- `good_with_cats`: Boolean for filtering animals that are designated as good with cats.
- `good_with_children`: Boolean for filtering animals that are designated as good with children.
- `good_with_dogs`: Boolean for filtering animals that are designated as good with dogs.
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Petpy - Python Wrapper for the Petfinder API

[![Documentation Status](https://readthedocs.org/projects/petpy/badge/?version=latest)](http://petpy.readthedocs.io/en/latest/?badge=latest)
[![CircleCI](https://circleci.com/gh/aschleg/petpy/tree/master.svg?style=svg)](https://circleci.com/gh/aschleg/petpy/tree/master)
[![Coverage Status](https://coveralls.io/repos/github/aschleg/petpy/badge.svg?branch=master)](https://coveralls.io/github/aschleg/petpy?branch=master)
[![codecov](https://codecov.io/gh/aschleg/petpy/branch/master/graph/badge.svg)](https://codecov.io/gh/aschleg/petpy)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ac2a4c228a9e425ba11af69f7a5c9e51)](https://www.codacy.com/app/aschleg/petpy?utm_source=github.com&utm_medium=referral&utm_content=aschleg/petpy&utm_campaign=Badge_Grade)
Expand Down
3 changes: 2 additions & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ pandas>=1.0.0
requests>=2.18.4
ratelimit>=2.2.1
backoff>=1.11.1
setuptools
setuptools
pytest-recording
178 changes: 100 additions & 78 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import os
import pytest
import vcr
from dotenv import load_dotenv
from pandas import DataFrame
import time

from pandas import DataFrame
from dotenv import load_dotenv
from petpy.api import Petfinder


tape = vcr.VCR(
cassette_library_dir='tests/cassettes',
serializer='json',
record_mode='once'
record_mode='all'
)

#load_dotenv('../.env')
load_dotenv('.env')
key = os.environ.get('PETPY_PETFINDER_KEY')
secret_key = os.environ.get('PETPY_PETFINDER_SECRET_KEY')

Expand All @@ -28,19 +30,21 @@ def test_authentication():


def authenticate():
petf = Petfinder(key=key, secret=secret_key)

return petf
pf = Petfinder(key=key, secret=secret_key)
return pf


petf = authenticate()
pf = authenticate()


@vcr.use_cassette('tests/cassettes/animal_types.yml')
def test_animal_types():
response1 = petf.animal_types()
response2 = petf.animal_types('cat')
response3 = petf.animal_types(['cat', 'dog'])
time.sleep(2)
response1 = pf.animal_types()
time.sleep(2)
response2 = pf.animal_types('cat')
time.sleep(2)
response3 = pf.animal_types(['cat', 'dog'])

assert isinstance(response1, dict)
assert isinstance(response2, dict)
Expand All @@ -51,22 +55,30 @@ def test_animal_types():
assert str.lower(response3['types'][1]['name']) == 'dog'

with pytest.raises(ValueError):
petf.animal_types(types='elephant')
time.sleep(2)
pf.animal_types(types='elephant')
with pytest.raises(ValueError):
petf.animal_types(types=['dragon', 'unicorn'])
time.sleep(2)
pf.animal_types(types=['dragon', 'unicorn'])
with pytest.raises(TypeError):
petf.animal_types(types={})
time.sleep(2)
pf.animal_types(types={})


@vcr.use_cassette('tests/cassettes/breeds.yml')
def test_breeds():

response1 = petf.breeds()
response1_df = petf.breeds(return_df=True)
response2 = petf.breeds('cat')
response2_df = petf.breeds('cat', return_df=True)
response3 = petf.breeds(['cat', 'dog'])
response3_df = petf.breeds(['cat', 'dog'], return_df=True)
time.sleep(2)
response1 = pf.breeds()
time.sleep(2)
response1_df = pf.breeds(return_df=True)
time.sleep(2)
response2 = pf.breeds('cat')
time.sleep(2)
response2_df = pf.breeds('cat', return_df=True)
time.sleep(2)
response3 = pf.breeds(['cat', 'dog'])
time.sleep(2)
response3_df = pf.breeds(['cat', 'dog'], return_df=True)

assert isinstance(response1, dict)
assert len(list(set(list(response1['breeds'].keys())).difference(animal_types))) == 0
Expand All @@ -81,44 +93,55 @@ def test_breeds():
assert isinstance(response3_df, DataFrame)

with pytest.raises(ValueError):
petf.breeds(types='elephant')
time.sleep(2)
pf.breeds(types='elephant')
with pytest.raises(ValueError):
petf.breeds(types=['dragon', 'unicorn'])
time.sleep(2)
pf.breeds(types=['dragon', 'unicorn'])
with pytest.raises(TypeError):
petf.breeds(types={})
time.sleep(2)
pf.breeds(types={})


@vcr.use_cassette('tests/cassettes/animals.yml')
def test_animals():
response1 = petf.animals()
response1_df = petf.animals(return_df=True)
response2 = petf.animals(results_per_page=50, pages=3)
response2_df = petf.animals(results_per_page=50, pages=3, return_df=True)
response1 = pf.animals()
time.sleep(2)
response1_df = pf.animals(return_df=True)
time.sleep(2)
response2 = pf.animals(results_per_page=50, pages=3)
time.sleep(2)
response2_df = pf.animals(results_per_page=50, pages=3, return_df=True)

animal_ids = []
for i in response1['animals'][0:3]:
animal_ids.append(i['id'])

response3 = petf.animals(animal_id=animal_ids, results_per_page=5)
response3_df = petf.animals(animal_id=animal_ids, return_df=True, results_per_page=5)

response4 = petf.animals(animal_id=animal_ids[0], results_per_page=5)
response4_df = petf.animals(animal_id=animal_ids[0], return_df=True, results_per_page=5)

response5 = petf.animals(good_with_children=1, good_with_cats=1, results_per_page=5)

response6 = petf.animals(before_date='2020-06-30', after_date='2020-01-01', results_per_page=5)
response7 = petf.animals(before_date='2020-06-30 0:0:0', after_date='2020-01-01 12:00:00', results_per_page=5)

response8 = petf.animals(good_with_dogs=1, results_per_page=5)
response9 = petf.animals(good_with_dogs=1, good_with_cats=1, good_with_children=1, return_df=True,
results_per_page=5)
response10 = petf.animals(special_needs=1, house_trained=1, declawed=1, return_df=True, results_per_page=5)

time.sleep(2)
response3 = pf.animals(animal_id=animal_ids, results_per_page=5)
time.sleep(2)
response3_df = pf.animals(animal_id=animal_ids, return_df=True, results_per_page=5)
time.sleep(2)
response4 = pf.animals(animal_id=animal_ids[0], results_per_page=5)
time.sleep(2)
response4_df = pf.animals(animal_id=animal_ids[0], return_df=True, results_per_page=5)
time.sleep(2)
response5 = pf.animals(good_with_children=1, good_with_cats=1, results_per_page=5)
time.sleep(2)
response6 = pf.animals(before_date='2020-06-30', after_date='2020-01-01', results_per_page=5)
time.sleep(2)
response7 = pf.animals(before_date='2020-06-30 0:0:0', after_date='2020-01-01 12:00:00', results_per_page=5)
time.sleep(2)
response8 = pf.animals(good_with_dogs=1, results_per_page=5)
time.sleep(2)
response9 = pf.animals(good_with_dogs=1, good_with_cats=1, good_with_children=1, return_df=True,
results_per_page=5)
time.sleep(2)
response10 = pf.animals(special_needs=1, house_trained=1, declawed=1, return_df=True, results_per_page=5)
time.sleep(2)
with pytest.raises(ValueError):
petf.animals(after_date='2021-07-02', before_date='2021-07-01', results_per_page=5)

response11 = petf.animals(status=['found', 'adoptable'], results_per_page=5)
pf.animals(after_date='2021-07-02', before_date='2021-07-01', results_per_page=5)
time.sleep(2)
response11 = pf.animals(status=['found', 'adoptable'], results_per_page=5)

assert isinstance(response1, dict)
assert len(response1['animals']) == 20
Expand Down Expand Up @@ -164,20 +187,19 @@ def test_animals():

@vcr.use_cassette('tests/cassettes/organizations.yml')
def test_organizations():
response1 = petf.organizations()
response1_df = petf.organizations(return_df=True)
response2 = petf.organizations(results_per_page=50, pages=3)
response2_df = petf.organizations(results_per_page=50, pages=3, return_df=True)
response1 = pf.organizations()
response1_df = pf.organizations(return_df=True)
response2 = pf.organizations(results_per_page=50, pages=3)
response2_df = pf.organizations(results_per_page=50, pages=3, return_df=True)

org_ids = []
for i in response1['organizations'][0:3]:
org_ids.append(i['id'])

response3 = petf.organizations(organization_id=org_ids)
response3_df = petf.organizations(organization_id=org_ids, return_df=True)

response4 = petf.organizations(organization_id=org_ids[0])
response4_df = petf.organizations(organization_id=org_ids[0], return_df=True)

response3 = pf.organizations(organization_id=org_ids)
response3_df = pf.organizations(organization_id=org_ids, return_df=True)
response4 = pf.organizations(organization_id=org_ids[0])
response4_df = pf.organizations(organization_id=org_ids[0], return_df=True)

assert isinstance(response1, dict)
assert len(response1['organizations']) == 20
Expand Down Expand Up @@ -216,42 +238,42 @@ def test_check_parameters():
good_with_dogs = 'yes'

with pytest.raises(ValueError):
petf.animals(size=size1)
pf.animals(size=size1)
with pytest.raises(ValueError):
petf.animals(size=[size1, size2])
pf.animals(size=[size1, size2])
with pytest.raises(ValueError):
petf.animals(gender=gender1)
pf.animals(gender=gender1)
with pytest.raises(ValueError):
petf.animals(gender=[gender1, gender2])
pf.animals(gender=[gender1, gender2])
with pytest.raises(ValueError):
petf.animals(age=age1)
pf.animals(age=age1)
with pytest.raises(ValueError):
petf.animals(age=[age1, age2])
pf.animals(age=[age1, age2])
with pytest.raises(ValueError):
petf.animals(coat=coat1)
pf.animals(coat=coat1)
with pytest.raises(ValueError):
petf.animals(coat=[coat1, coat2])
pf.animals(coat=[coat1, coat2])
with pytest.raises(ValueError):
petf.animals(status=status)
pf.animals(status=status)
with pytest.raises(ValueError):
petf.animals(sort=sort)
pf.animals(sort=sort)
with pytest.raises(ValueError):
petf.animals(distance=distance_int)
pf.animals(distance=distance_int)
with pytest.raises(ValueError):
petf.animals(distance=distance_str)
pf.animals(distance=distance_str)
with pytest.raises(ValueError):
petf.animals(results_per_page=limit_int)
pf.animals(results_per_page=limit_int)
with pytest.raises(ValueError):
petf.animals(results_per_page=limit_str)
pf.animals(results_per_page=limit_str)
with pytest.raises(ValueError):
petf.animals(declawed=declawed)
pf.animals(declawed=declawed)
with pytest.raises(ValueError):
petf.animals(house_trained=house_trained)
pf.animals(house_trained=house_trained)
with pytest.raises(ValueError):
petf.animals(special_needs=special_needs)
pf.animals(special_needs=special_needs)
with pytest.raises(ValueError):
petf.animals(good_with_cats=good_with_cats)
pf.animals(good_with_cats=good_with_cats)
with pytest.raises(ValueError):
petf.animals(good_with_dogs=good_with_dogs)
pf.animals(good_with_dogs=good_with_dogs)
with pytest.raises(ValueError):
petf.animals(good_with_children=good_with_children)
pf.animals(good_with_children=good_with_children)

0 comments on commit ff3d88e

Please sign in to comment.