From 3a87a64a465fed7a87d3cceef40ce3f128f0db5b Mon Sep 17 00:00:00 2001 From: James Christopher Date: Tue, 12 Dec 2017 11:06:21 -0800 Subject: [PATCH 1/7] initial commit --- .idea/News-API-python.iml | 11 ++++++ .idea/encodings.xml | 6 ++++ .idea/inspectionProfiles/Project_Default.xml | 33 ++++++++++++++++++ .idea/misc.xml | 7 ++++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 6 ++++ README.md | 26 +++++++++++++++ newsapi/__init__.py | 4 +++ newsapi/client.py | 23 +++++++++++++ newsapi/errors.py | 5 +++ newsapi/resources.py | 35 ++++++++++++++++++++ setup.py | 29 ++++++++++++++++ 12 files changed, 193 insertions(+) create mode 100644 .idea/News-API-python.iml create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 newsapi/__init__.py create mode 100644 newsapi/client.py create mode 100644 newsapi/errors.py create mode 100644 newsapi/resources.py create mode 100644 setup.py diff --git a/.idea/News-API-python.iml b/.idea/News-API-python.iml new file mode 100644 index 0000000..1ce878e --- /dev/null +++ b/.idea/News-API-python.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..2701819 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,33 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..999ac79 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + ApexVCS + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9d45f05 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 2841b71..16d4a3d 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,29 @@ Coming soon... this is where our officially supported SDK for Python is going to ## Developers... we need you! We need some help fleshing out this repo. If you're a Python dev with experience building PyPI-compatible libraries and web API wrappers, we're offering a reward of $250 to help us get started. For more info please email support@newsapi.org, or dive right in and send us a pull request. + + +# Usage +``` +import newsapi +newsapi.API_KEY = '' + +# list of all sources +newsapi.Sources().list() + +# list of American sources +newsapi.Sources().list(country='us') + +# list of American Gaming sources +newsapi.Sources().list(**{'country': 'us', 'category': 'gaming'}) + +# Same pattern for TopHeadlines and Everything + +newsapi.TopHeadlines().list() +newsapi.TopHeadlines().list(arg1=..., arg2=...) +newsapi.TopHeadlines().list(**{'arg1':..., 'arg2':...}) + +newsapi.Everything().list() +newsapi.Everything().list(arg1=..., arg2=...) +newsapi.Everything().list(**{'arg1':..., 'arg2':...}) +``` diff --git a/newsapi/__init__.py b/newsapi/__init__.py new file mode 100644 index 0000000..7e63e4a --- /dev/null +++ b/newsapi/__init__.py @@ -0,0 +1,4 @@ +API_KEY = None +API_URL_BASE = 'https://newsapi.org/v2/' + +from . resources import TopHeadlines, Everything, Sources \ No newline at end of file diff --git a/newsapi/client.py b/newsapi/client.py new file mode 100644 index 0000000..f96e46d --- /dev/null +++ b/newsapi/client.py @@ -0,0 +1,23 @@ +import requests +from . errors import NewsAPIError + + +class Client: + + def __init__(self, api_url_base, timeout=80): + self._timeout = timeout + self._session = requests.Session() + + from newsapi import API_KEY + self._api_key = API_KEY + self._session.headers.update({'Authorization': self._api_key}) + + self._api_url_base = api_url_base + + def get(self, endpoint, params): + resp = self._session.get(self._api_url_base + endpoint, params=params) + try: + resp.raise_for_status() + return resp.json() + except requests.exceptions.HTTPError: + raise NewsAPIError(resp.json()) \ No newline at end of file diff --git a/newsapi/errors.py b/newsapi/errors.py new file mode 100644 index 0000000..d87fb74 --- /dev/null +++ b/newsapi/errors.py @@ -0,0 +1,5 @@ +class NewsAPIError(Exception): + + def __init__(self, response_json, *args, **kwargs): + message = '{code} : {message}'.format(**response_json) + super().__init__(message, *args, **kwargs) \ No newline at end of file diff --git a/newsapi/resources.py b/newsapi/resources.py new file mode 100644 index 0000000..2fd8159 --- /dev/null +++ b/newsapi/resources.py @@ -0,0 +1,35 @@ +from .client import Client +from newsapi import API_URL_BASE + + +class BaseResource: + + endpoint = None + + def list(self, **params): + client = Client(API_URL_BASE) + return client.get(self.endpoint, params) + + +class TopHeadlines(BaseResource): + + endpoint = 'top-headlines' + + def list(self, **params): + return super().list(**params)['articles'] + + +class Everything(BaseResource): + + endpoint = 'everything' + + def list(self, **params): + return super().list(**params)['articles'] + + +class Sources(BaseResource): + + endpoint = 'sources' + + def list(self, **params): + return super().list(**params)['sources'] diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..a3740f1 --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +from setuptools import setup, find_packages + +install_reqs = [ + 'requests', +] + +setup( + name='newsapi', + version='0.0.0', + description='Python client for the News-API REST API', + author='James Christopher', + author_email='jcahall@washington.edu', + packages=find_packages(), + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python', + 'Topic :: Internet :: WWW/HTTP', + ], + url='https://github.com/News-API-gh/News-API-python', + install_requires=install_reqs, +) \ No newline at end of file From 43da05cf26b52a400739f422769a028b36b614d5 Mon Sep 17 00:00:00 2001 From: James Christopher Date: Tue, 12 Dec 2017 11:08:22 -0800 Subject: [PATCH 2/7] update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7bbc71c..75ac08e 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,5 @@ ENV/ # mypy .mypy_cache/ + +.idea/ \ No newline at end of file From 2d5ae65400efc80f2d892ef1c7f695a04ba13c41 Mon Sep 17 00:00:00 2001 From: James Christopher Date: Tue, 12 Dec 2017 11:10:19 -0800 Subject: [PATCH 3/7] update gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 75ac08e..4956e1a 100644 --- a/.gitignore +++ b/.gitignore @@ -100,4 +100,5 @@ ENV/ # mypy .mypy_cache/ -.idea/ \ No newline at end of file +.idea/ +*.iml \ No newline at end of file From 28e9ca9ffacadf172d33faad63ee87794695117c Mon Sep 17 00:00:00 2001 From: James Christopher Date: Tue, 12 Dec 2017 11:13:17 -0800 Subject: [PATCH 4/7] fixed untracked files --- .idea/News-API-python.iml | 11 ------- .idea/encodings.xml | 6 ---- .idea/inspectionProfiles/Project_Default.xml | 33 -------------------- .idea/misc.xml | 7 ----- .idea/modules.xml | 8 ----- .idea/vcs.xml | 6 ---- 6 files changed, 71 deletions(-) delete mode 100644 .idea/News-API-python.iml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/News-API-python.iml b/.idea/News-API-python.iml deleted file mode 100644 index 1ce878e..0000000 --- a/.idea/News-API-python.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 97626ba..0000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 2701819..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 999ac79..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - ApexVCS - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 9d45f05..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 009fc41f51f0effa947cab32ae81755a52eb7aad Mon Sep 17 00:00:00 2001 From: James Christopher Date: Tue, 12 Dec 2017 11:17:20 -0800 Subject: [PATCH 5/7] rejigger client base url code --- newsapi/client.py | 8 +++++--- newsapi/resources.py | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/newsapi/client.py b/newsapi/client.py index f96e46d..302797d 100644 --- a/newsapi/client.py +++ b/newsapi/client.py @@ -1,10 +1,11 @@ import requests -from . errors import NewsAPIError + +from .errors import NewsAPIError class Client: - def __init__(self, api_url_base, timeout=80): + def __init__(self, timeout=80): self._timeout = timeout self._session = requests.Session() @@ -12,7 +13,8 @@ def __init__(self, api_url_base, timeout=80): self._api_key = API_KEY self._session.headers.update({'Authorization': self._api_key}) - self._api_url_base = api_url_base + from newsapi import API_URL_BASE + self._api_url_base = API_URL_BASE def get(self, endpoint, params): resp = self._session.get(self._api_url_base + endpoint, params=params) diff --git a/newsapi/resources.py b/newsapi/resources.py index 2fd8159..f128d9a 100644 --- a/newsapi/resources.py +++ b/newsapi/resources.py @@ -1,5 +1,4 @@ from .client import Client -from newsapi import API_URL_BASE class BaseResource: @@ -7,7 +6,7 @@ class BaseResource: endpoint = None def list(self, **params): - client = Client(API_URL_BASE) + client = Client() return client.get(self.endpoint, params) From e30e525042e0dee8c63f475e94205a7f56015c58 Mon Sep 17 00:00:00 2001 From: James Christopher Date: Thu, 14 Dec 2017 21:20:45 -0800 Subject: [PATCH 6/7] move client construction into Resource __init__ --- newsapi/client.py | 3 +-- newsapi/resources.py | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/newsapi/client.py b/newsapi/client.py index 302797d..e0c8187 100644 --- a/newsapi/client.py +++ b/newsapi/client.py @@ -5,8 +5,7 @@ class Client: - def __init__(self, timeout=80): - self._timeout = timeout + def __init__(self): self._session = requests.Session() from newsapi import API_KEY diff --git a/newsapi/resources.py b/newsapi/resources.py index f128d9a..f2b5a30 100644 --- a/newsapi/resources.py +++ b/newsapi/resources.py @@ -5,9 +5,11 @@ class BaseResource: endpoint = None + def __init__(self): + self.client = Client() + def list(self, **params): - client = Client() - return client.get(self.endpoint, params) + return self.client.get(self.endpoint, params) class TopHeadlines(BaseResource): From a2f56b122f3371d2e1a9f6595a80cc3ec555610a Mon Sep 17 00:00:00 2001 From: James Christopher Date: Wed, 25 Apr 2018 21:05:04 -0700 Subject: [PATCH 7/7] refactor --- newsapi/resources.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/newsapi/resources.py b/newsapi/resources.py index f2b5a30..71bfefc 100644 --- a/newsapi/resources.py +++ b/newsapi/resources.py @@ -4,33 +4,28 @@ class BaseResource: endpoint = None + item = None def __init__(self): self.client = Client() def list(self, **params): - return self.client.get(self.endpoint, params) + return self.client.get(self.endpoint, params)[self.item] class TopHeadlines(BaseResource): endpoint = 'top-headlines' - - def list(self, **params): - return super().list(**params)['articles'] + item = 'articles' class Everything(BaseResource): endpoint = 'everything' - - def list(self, **params): - return super().list(**params)['articles'] + item = 'articles' class Sources(BaseResource): endpoint = 'sources' - - def list(self, **params): - return super().list(**params)['sources'] + item = 'sources'