aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Reitz <me@kennethreitz.com>2011-06-23 02:59:49 -0400
committerKenneth Reitz <me@kennethreitz.com>2011-06-23 02:59:49 -0400
commitecad4a9e256a10208b5e97d66f88416fecdf9cb3 (patch)
tree9c8922645118812cb2c3dd7bce57b46cb78f6a66
parentclean slate (diff)
downloadpython-github3-ecad4a9e256a10208b5e97d66f88416fecdf9cb3.tar.xz
python-github3-ecad4a9e256a10208b5e97d66f88416fecdf9cb3.zip
updates
-rw-r--r--github3/api.py76
-rw-r--r--github3/config.py61
-rw-r--r--github3/core.py17
-rw-r--r--github3/helpers.py95
4 files changed, 249 insertions, 0 deletions
diff --git a/github3/api.py b/github3/api.py
index 8d2361d..b8b7617 100644
--- a/github3/api.py
+++ b/github3/api.py
@@ -10,3 +10,79 @@ This module implements the GitHub3 API wrapper objects.
"""
+import urllib
+
+
+from .config import settings
+from .helpers import is_collection
+from .packages import omnijson as json
+
+
+class GithubCore(object):
+ """The main GitHub API Interface."""
+
+ def __init__(self):
+ self.username = None
+ self._auth = None
+
+
+ @staticmethod
+ def _resource_serialize(o):
+ """Returns JSON serialization of given object."""
+ return json.dumps(o)
+
+
+ @staticmethod
+ def _resource_deserialize(s):
+ """Returns dict deserialization of a given JSON string."""
+
+ try:
+ return json.loads(s)
+ except ValueError:
+ raise ResponseError('The API Response was not valid.')
+
+
+ def _generate_url(self, resource, params):
+ """Generates Readability API Resource URL."""
+
+ if is_collection(resource):
+ resource = map(str, resource)
+ resource = '/'.join(resource)
+
+ if params:
+ resource += '?%s' % (urllib.urlencode(params))
+
+ return settings.domain + '/' + resource
+
+
+class Github(GithubCore):
+ """The user-facing GitHub API Interface."""
+
+ def __init__(self):
+ super(Github, self).__init__()
+
+
+# ----------
+# Exceptions
+# ----------
+
+class APIError(Exception):
+ """There was an API Error."""
+
+class PermissionsError(APIError):
+ """You do not have proper permission."""
+
+class AuthenticationError(APIError):
+ """Authentication failed."""
+
+class ResponseError(APIError):
+ """The API Response was unexpected."""
+
+class MissingError(APIError):
+ """The Resource does not exist."""
+
+class BadRequestError(APIError):
+ """The request could not be understood due to bad syntax. Check your request and try again."""
+
+class ServerError(APIError):
+ """The server encountered an error and was unable to complete your request.""" \ No newline at end of file
diff --git a/github3/config.py b/github3/config.py
new file mode 100644
index 0000000..3a9705c
--- /dev/null
+++ b/github3/config.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+
+"""
+github3.config
+~~~~~~~~~~~~~~
+
+This module provides the GitHub3 settings feature set.
+
+:copyright: (c) 2011 by Kenneth Reitz.
+:license: ISC, see LICENSE for more details.
+"""
+
+
+class Settings(object):
+ _singleton = dict()
+
+ # attributes with defaults
+ __attrs__ = ('timeout',)
+
+ def __init__(self, **kwargs):
+ super(Settings, self).__init__()
+
+ self.__dict__ = self._singleton
+
+
+ def __call__(self, *args, **kwargs):
+ # new instance of class to call
+ r = self.__class__()
+
+ # cache previous settings for __exit__
+ r.__cache = self.__dict__.copy()
+ map(self.__cache.setdefault, self.__attrs__)
+
+ # set new settings
+ self.__dict__.update(*args, **kwargs)
+
+ return r
+
+
+ def __enter__(self):
+ pass
+
+
+ def __exit__(self, *args):
+
+ # restore cached copy
+ self.__dict__.update(self.__cache.copy())
+ del self.__cache
+
+
+ def __getattribute__(self, key):
+ if key in object.__getattribute__(self, '__attrs__'):
+ try:
+ return object.__getattribute__(self, key)
+ except AttributeError:
+ return None
+ return object.__getattribute__(self, key)
+
+
+settings = Settings()
+settings.domain = 'https://api.github.com' \ No newline at end of file
diff --git a/github3/core.py b/github3/core.py
index fcee886..4256b4a 100644
--- a/github3/core.py
+++ b/github3/core.py
@@ -8,3 +8,20 @@ This module contains the core GitHub3 interface.
"""
+import requests
+
+from .api import Github, settings
+
+
+__version__ = '0.0.1'
+__license__ = 'ISC'
+__author__ = 'Kenneth Reitz'
+
+
+
+def basic(username, password):
+ pass
+
+
+def anon():
+ pass \ No newline at end of file
diff --git a/github3/helpers.py b/github3/helpers.py
new file mode 100644
index 0000000..3b148d6
--- /dev/null
+++ b/github3/helpers.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+
+"""
+github3.helpers
+~~~~~~~~~~~~~~~
+
+This module provides various helper functions to the rest of the package.
+"""
+
+
+from datetime import datetime
+
+from dateutil.parser import parse as parse_datetime
+
+
+def is_collection(obj):
+ """Tests if an object is a collection."""
+
+ col = getattr(obj, '__getitem__', False)
+ val = False if (not col) else True
+
+ if isinstance(obj, basestring):
+ val = False
+
+ return val
+
+
+def to_python(obj, in_dict, string_keys=None, date_keys=None, object_map=None, **kwargs):
+ """Extends a given object for API Consumption.
+
+ :param obj: Object to extend.
+ :param in_dict: Dict to extract data from.
+ :param string_keys: List of in_dict keys that will be extracted as strings.
+ :param date_keys: List of in_dict keys that will be extrad as datetimes.
+ :param object_map: Dict of {key, obj} map, for nested object results.
+ """
+
+ if string_keys:
+ for in_key in string_keys:
+ # print in_key
+ obj.__dict__[in_key] = in_dict.get(in_key)
+
+ if date_keys:
+ for in_key in date_keys:
+ in_date = in_dict.get(in_key)
+ try:
+ out_date = datetime.strptime(in_date, '%Y-%m-%d %H:%M:%S')
+ except TypeError:
+ out_date = None
+
+ obj.__dict__[in_key] = out_date
+
+ if object_map:
+
+ for (k, v) in object_map.items():
+ obj.__dict__[k] = v.new_from_dict(in_dict.get(k))
+
+ obj.__dict__.update(kwargs)
+
+ return obj
+
+
+def to_api(in_dict, int_keys=None, date_keys=None):
+ """Extends a given object for API Production."""
+
+ # Cast all int_keys to int()
+ if int_keys:
+ for in_key in int_keys:
+ if (in_key in in_dict) and (in_dict.get(in_key, None) is not None):
+ in_dict[in_key] = int(in_dict[in_key])
+
+ # Cast all date_keys to datetime.isoformat
+ if date_keys:
+ for in_key in date_keys:
+ if (in_key in in_dict) and (in_dict.get(in_key, None) is not None):
+
+ _from = in_dict[in_key]
+
+ if isinstance(_from, basestring):
+ dtime = parse_datetime(_from)
+
+ elif isinstance(_from, datetime):
+ dtime = _from
+
+ in_dict[in_key] = dtime.isoformat()
+
+ elif (in_key in in_dict) and in_dict.get(in_key, None) is None:
+ del in_dict[in_key]
+
+ # Remove all Nones
+ for k, v in in_dict.items():
+ if v is None:
+ del in_dict[k]
+
+ return in_dict