aboutsummaryrefslogtreecommitdiffstats
path: root/pygithub3
diff options
context:
space:
mode:
authorDavid Medina <davidmedina9@gmail.com>2012-02-03 14:45:32 +0100
committerDavid Medina <davidmedina9@gmail.com>2012-02-03 14:46:54 +0100
commitf01bc94a33d8644da65b5fa895c222e9ee057b50 (patch)
tree3bfc837901a54f97a30f1d24431d8322906de192 /pygithub3
parentPypi environment by setuptools (diff)
downloadpython-github3-f01bc94a33d8644da65b5fa895c222e9ee057b50.tar.xz
python-github3-f01bc94a33d8644da65b5fa895c222e9ee057b50.zip
Fix imports to new environment
Absolute imports as PEP8 tells
Diffstat (limited to 'pygithub3')
-rw-r--r--pygithub3/__init__.py8
-rw-r--r--pygithub3/core/__init__.py0
-rw-r--r--pygithub3/core/client.py96
-rw-r--r--pygithub3/core/errors.py41
-rw-r--r--pygithub3/core/resources/__init__.py87
-rw-r--r--pygithub3/core/resources/users/__init__.py4
-rw-r--r--pygithub3/core/resources/users/emails.py9
-rw-r--r--pygithub3/core/resources/users/followers.py0
-rw-r--r--pygithub3/core/resources/users/keys.py0
-rw-r--r--pygithub3/core/resources/users/user.py25
-rw-r--r--pygithub3/github.py2
-rw-r--r--pygithub3/models/__init__.py1
-rw-r--r--pygithub3/models/base.py58
-rw-r--r--pygithub3/models/users.py22
-rw-r--r--pygithub3/services/__init__.py0
-rw-r--r--pygithub3/services/base.py43
-rw-r--r--pygithub3/services/users.py45
-rw-r--r--pygithub3/tests/__init__.py0
-rw-r--r--pygithub3/tests/test_errors.py36
19 files changed, 477 insertions, 0 deletions
diff --git a/pygithub3/__init__.py b/pygithub3/__init__.py
new file mode 100644
index 0000000..7c48d06
--- /dev/null
+++ b/pygithub3/__init__.py
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+__title__ = 'pygithub3'
+__version__ = '0.1'
+__author__ = 'David Medina'
+__license__ = 'ISC'
+__copyright__ = 'Copyright 2012 David Medina'
diff --git a/pygithub3/core/__init__.py b/pygithub3/core/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pygithub3/core/__init__.py
diff --git a/pygithub3/core/client.py b/pygithub3/core/client.py
new file mode 100644
index 0000000..d4247af
--- /dev/null
+++ b/pygithub3/core/client.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+import requests
+
+from .errors import GithubError
+
+VALID_REQUEST_ARGS = set((
+ 'params', 'data', 'headers', 'cookies', 'files', 'auth', 'timeout',
+ 'allow_redirects', 'proxies', 'return_response', 'config',
+ 'prefetch', 'verify'))
+
+
+class Client(object):
+ """ Client to send configurated requests"""
+
+ def __init__(self, **kwargs):
+ """
+ It can be configurated
+
+ :login, :password, :user, :repo, :token, :per_page, :base_url
+ """
+
+ self.requester = requests.session()
+ self.config = {
+ 'per_page': 100,
+ 'base_url': 'https://api.github.com/'
+ }
+ self.config.update(kwargs)
+ self.set_credentials(self.config.get('login'),
+ self.config.get('password'))
+ self.set_token(self.config.get('token'))
+ self.__set_params(self.config)
+
+ @property
+ def user(self):
+ return self.config.get('user')
+
+ @user.setter
+ def set_user(self, user):
+ self.config['user'] = user
+
+ @property
+ def repo(self):
+ return self.config.get('repo')
+
+ @repo.setter
+ def set_repo(self, repo):
+ self.config['repo'] = repo
+
+ def set_credentials(self, login, password):
+ if login and password:
+ self.requester.auth = (login, password)
+
+ def set_token(self, token):
+ if token:
+ self.requester.params['access_token'] = token
+
+ def __set_params(self, config):
+ self.requester.params['per_page'] = config.get('per_page')
+
+ def __parse_kwargs(func):
+ """ Decorator to put extra args into requests.params """
+
+ def wrapper(self, verb, resource, **kwargs):
+ diffs = kwargs.viewkeys() - VALID_REQUEST_ARGS
+ new_params = kwargs.get('params') or {}
+ new_params.update({key: kwargs[key] for key in diffs})
+ kwargs['params'] = new_params
+ return func(self, verb, resource, **kwargs)
+ return wrapper
+
+ @__parse_kwargs
+ def request(self, verb, resource, **kwargs):
+ resource = "%s%s" % (self.config['base_url'], resource)
+ response = self.requester.request(verb, resource, **kwargs)
+ GithubError(response).process()
+ return response
+
+ def get(self, resource, **kwargs):
+ return self.request('get', resource, **kwargs)
+
+ def post(self, resource, **kwargs):
+ return self.request('post', resource, **kwargs)
+
+ def patch(self, resource, **kwargs):
+ return self.request('patch', resource, **kwargs)
+
+ def put(self, resource, **kwargs):
+ return self.request('put', resource, **kwargs)
+
+ def delete(self, resource, **kwargs):
+ return self.request('delete', resource, **kwargs)
+
+ def head(self, resource, **kwargs):
+ return self.request('head', resource, **kwargs)
diff --git a/pygithub3/core/errors.py b/pygithub3/core/errors.py
new file mode 100644
index 0000000..0d58c16
--- /dev/null
+++ b/pygithub3/core/errors.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+import json
+
+
+class BadRequest(Exception):
+ pass
+
+
+class UnprocessableEntity(Exception):
+ pass
+
+
+class GithubError(object):
+ """ Handler for API errors """
+
+ def __init__(self, response):
+ self.response = response
+ self.status_code = response.status_code
+ try:
+ self.debug = json.loads(response.content)
+ except (ValueError, TypeError):
+ self.debug = {'message': response.content}
+
+ def error_400(self):
+ return BadRequest("400 - %s" % self.debug.get('message'))
+
+ def error_422(self):
+ errors = self.debug.get('errors')
+ if errors:
+ errors = ['{resource}: {code} => {field}'.format(**error)
+ for error in errors]
+ return UnprocessableEntity(
+ '422 - %s %s' % (self.debug.get('message'), errors))
+
+ def process(self):
+ raise_error = getattr(self, 'error_%s' % self.status_code, False)
+ if raise_error:
+ raise raise_error()
+ self.response.raise_for_status()
diff --git a/pygithub3/core/resources/__init__.py b/pygithub3/core/resources/__init__.py
new file mode 100644
index 0000000..bca9607
--- /dev/null
+++ b/pygithub3/core/resources/__init__.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+import re
+
+ABS_IMPORT_PREFIX = 'pygithub3.core.resources'
+
+
+class UriNotFound(Exception):
+ pass
+
+
+class UriInvalid(Exception):
+ pass
+
+
+class Resource(object):
+ """ """
+
+ def __init__(self, args):
+ """ """
+ self.args = args
+ self.validate()
+ self.uri = self.set_uri()
+
+ def validate(self, args):
+ raise NotImplementedError
+
+ def set_uri(self):
+ raise NotImplementedError
+
+ def get_uri(self):
+ return str(self.uri).strip('/')
+
+ def get_model(self):
+ return getattr(self, 'model', '')
+
+ def __getattr__(self, name):
+ return self.args.get(name)
+
+ def __str__(self):
+ return self.get_uri()
+
+
+class Factory(object):
+ """ """
+
+ import_pattern = re.compile(r'^(\w+\.)+\w+$')
+
+ def __init__(self, **kwargs):
+ self.args = kwargs
+
+ def __validate(func):
+ """ """
+
+ def wrapper(self, resource_path):
+ if not Factory.import_pattern.match(resource_path):
+ raise UriInvalid("'%s' isn't valid form" % resource_path)
+ return func(self, resource_path.lower())
+ return wrapper
+
+ def __dispatch(func):
+ """ """
+
+ from importlib import import_module
+
+ def wrapper(self, resource_path):
+ module_chunk, s, uri_chunk = resource_path.rpartition('.')
+ try:
+ # TODO: CamelCase and under_score support, now only Class Name
+ module = import_module('%s.%s'
+ % (ABS_IMPORT_PREFIX, module_chunk))
+ uri = getattr(module, uri_chunk.capitalize())
+ except ImportError:
+ raise UriNotFound("'%s' module does not exists" % module_chunk)
+ except AttributeError:
+ raise UriNotFound("'%s' uri doesn't exists into '%s' module"
+ % (uri_chunk.capitalize(), module_chunk))
+ return func(self, uri)
+ return wrapper
+
+ @__validate
+ @__dispatch
+ def __call__(self, resource_class=''):
+ resource = resource_class(self.args)
+ assert isinstance(resource, Resource)
+ return resource
diff --git a/pygithub3/core/resources/users/__init__.py b/pygithub3/core/resources/users/__init__.py
new file mode 100644
index 0000000..84759a2
--- /dev/null
+++ b/pygithub3/core/resources/users/__init__.py
@@ -0,0 +1,4 @@
+# -*- encoding: utf-8 -*-
+
+from pygithub3.core.resources import Resource
+from user import *
diff --git a/pygithub3/core/resources/users/emails.py b/pygithub3/core/resources/users/emails.py
new file mode 100644
index 0000000..18d520c
--- /dev/null
+++ b/pygithub3/core/resources/users/emails.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from . import Resource
+#from pygithub3.models.
+
+
+class List(Resource):
+ pass
diff --git a/pygithub3/core/resources/users/followers.py b/pygithub3/core/resources/users/followers.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pygithub3/core/resources/users/followers.py
diff --git a/pygithub3/core/resources/users/keys.py b/pygithub3/core/resources/users/keys.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pygithub3/core/resources/users/keys.py
diff --git a/pygithub3/core/resources/users/user.py b/pygithub3/core/resources/users/user.py
new file mode 100644
index 0000000..1399ff8
--- /dev/null
+++ b/pygithub3/core/resources/users/user.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from . import Resource
+from pygithub3.models.users import User
+
+__all__ = ('Get', 'Update')
+
+
+class Get(Resource):
+
+ model = User
+
+ def validate(self):
+ pass
+
+ def set_uri(self):
+ if self.user:
+ return 'users/%s' % self.user
+ else:
+ return 'user'
+
+
+class Update(Resource):
+ pass
diff --git a/pygithub3/github.py b/pygithub3/github.py
new file mode 100644
index 0000000..ff6ea1e
--- /dev/null
+++ b/pygithub3/github.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
diff --git a/pygithub3/models/__init__.py b/pygithub3/models/__init__.py
new file mode 100644
index 0000000..dae354a
--- /dev/null
+++ b/pygithub3/models/__init__.py
@@ -0,0 +1 @@
+# -*- encoding: utf-8 -*-
diff --git a/pygithub3/models/base.py b/pygithub3/models/base.py
new file mode 100644
index 0000000..2f0cbd7
--- /dev/null
+++ b/pygithub3/models/base.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+
+class Model(object):
+
+ dates = ()
+ maps = {}
+ collection_maps = {}
+
+ def __init__(self, attrs):
+ """ """
+ self.attrs = attrs
+
+ def __getattr__(self, name):
+ try:
+ return self.attrs[name]
+ except KeyError:
+ raise AttributeError
+
+ @classmethod
+ def loads(self, raw_resource):
+ def parse_date(string_date):
+ from datetime import datetime
+ try:
+ date = datetime.strptime(string_date, '%Y-%m-%dT%H:%M:%SZ')
+ except TypeError:
+ date = None
+ return date
+
+ def parse_map(model, raw_resource):
+ if hasattr(raw_resource, 'items'):
+ return model.loads(raw_resource)
+
+ def parse_collection_map(model, raw_resources):
+ # Dict of resources (Ex: Gist file)
+ if hasattr(raw_resources, 'items'):
+ dict_map = {}
+ for key, raw_resource in raw_resources.items():
+ dict_map[key] = model.loads(raw_resource)
+ return dict_map
+ # list of resources
+ elif hasattr(raw_resources, '__iter__'):
+ return [model.loads(raw_resource)
+ for raw_resource in raw_resources]
+ raw_resource.update(
+ {attr: parse_date(raw_resource[attr])
+ for attr in self.dates if attr in raw_resource})
+ raw_resource.update(
+ {attr: parse_map(model, raw_resource[attr])
+ for attr, model in self.maps.items()
+ if attr in raw_resource})
+ raw_resource.update(
+ {attr: parse_collection_map(model, raw_resource[attr])
+ for attr, model in self.collection_maps.items()
+ if attr in raw_resource})
+
+ return self(raw_resource)
diff --git a/pygithub3/models/users.py b/pygithub3/models/users.py
new file mode 100644
index 0000000..0ceef90
--- /dev/null
+++ b/pygithub3/models/users.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from .base import Model
+
+__all__ = ('Plan', 'User')
+
+
+class Plan(Model):
+
+ def __str__(self):
+ return '<Plan (%s)>' % getattr(self, 'name', '')
+
+
+class User(Model):
+ """ """
+
+ maps = {'plan': Plan}
+ dates = ('created_at', )
+
+ def __str__(self):
+ return '<User (%s)>' % getattr(self, 'login', '')
diff --git a/pygithub3/services/__init__.py b/pygithub3/services/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pygithub3/services/__init__.py
diff --git a/pygithub3/services/base.py b/pygithub3/services/base.py
new file mode 100644
index 0000000..303b3a0
--- /dev/null
+++ b/pygithub3/services/base.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from pygithub3.core.client import Client
+
+
+class Base(object):
+
+ def __init__(self, **config):
+ self.client = Client(**config)
+
+ def get_user(self):
+ return self.client.user
+
+ def set_user(self, user):
+ self.client.user = user
+
+ def get_repo(self):
+ return self.client.repo
+
+ def set_repo(self, repo):
+ self.client.repo = repo
+
+ def _get_result(self, resource, **kwargs):
+ return Result(self.client.get, resource, **kwargs)
+
+
+class Result(object): # move
+
+ def __init__(self, method, resource, **kwargs):
+ self.method = method
+ self.resource = resource
+ self.args = kwargs
+
+ def __repr__(self):
+ pass
+
+ def process(self):
+ model = self.resource.get_model()
+ raw = self.method(self.resource, **self.args)
+ if model:
+ import json
+ return model.loads(json.loads(raw.content))
diff --git a/pygithub3/services/users.py b/pygithub3/services/users.py
new file mode 100644
index 0000000..70826f2
--- /dev/null
+++ b/pygithub3/services/users.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from .base import Base
+from pygithub3.core.resources import Factory
+
+
+class Keys(Base):
+
+ def list(self):
+ return self.get_resource('user/keys')
+
+
+class Followers(Base):
+
+ def list(self, user):
+ pass
+
+
+class Emails(Base):
+
+ def list(self):
+ pass
+
+ def add(self):
+ pass
+
+ def delete(self):
+ pass
+
+
+class User(Base):
+
+ def __init__(self, **kwargs):
+ self.keys = Keys(**kwargs)
+ self.emails = Emails(**kwargs)
+ self.followers = Followers(**kwargs)
+ super(User, self).__init__(**kwargs)
+
+ def get(self, user):
+ resource = Factory(user=user or self.client.user)
+ return self._get_result(resource('users.get'))
+
+ def update(self):
+ pass
diff --git a/pygithub3/tests/__init__.py b/pygithub3/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pygithub3/tests/__init__.py
diff --git a/pygithub3/tests/test_errors.py b/pygithub3/tests/test_errors.py
new file mode 100644
index 0000000..36f33d9
--- /dev/null
+++ b/pygithub3/tests/test_errors.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+from unittest import TestCase
+from requests.exceptions import HTTPError
+from core import client
+import errors
+import json
+
+class TestErrorsWithoutAuth(TestCase):
+ """docstring for TestRequestsLibrary"""
+
+ def setUp(self):
+ self.client = client.Client()
+
+ def test_malformed_url(self):
+ self.assertRaises(HTTPError, self.client.request, 'get', 'fake')
+
+class TestErrorsAuthenticated(TestCase):
+ """docstring for TestErrorsAuthenticaed"""
+
+ def setUp(self):
+ self.client = client.Client(
+ login='pygit',
+ password='pygithub3'
+ )
+
+ def test_400_parsing_json(self):
+ data = 'strinf'
+ self.assertRaises(errors.BadRequest, self.client.request,
+ 'post', 'user/repos', data=data)
+
+ def test_400_json_hash(self):
+ data = json.dumps({'names': 'david'})
+ with self.assertRaises(errors.UnprocessableEntity) as cm:
+ self.client.request('post', 'user/repos', data=data)