Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
Added user functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
aravenel committed Sep 25, 2012
1 parent 0ddb7a6 commit 2bd60ec
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 14 deletions.
8 changes: 8 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Copyright (c) 2012 Alex Ravenel

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,49 @@ metadata.

###Get Project Comments
```python
proj.get_comments()
comments = proj.get_comments()
```
Method of the Project object. Returns list of dictionaries, each dictionary
representing a single comment and its metadata.

##User functionality
TBD.
###Search for Users
```python
users = behance.get_users('term1', 'term2', filter_key='filter_value')
```
Works just like project_search.

###Get Single User Details
```python
user = behance.get_user(user_id_or_username)
```

###Get User Projects
```python
user_projects = user.get_projects()
```

###Get User Works in Progress
```python
user_wips = user.get_wips()
```

###Get User Appreciations
```python
user_appreciations = user.get_appreciations()
```

###Get User Collections
```python
user_collections = user.get_collections()
```

##Work in Progress Functionality
TBD.

#Exceptions
Unfortunately, they happen. If an exception happens in the calling of the API
(e.g. a timeout), the library will raise the exception from the underlying Requests
library. If the response from the Behance API is anything other than status code
200, it will raise a BehanceException exception with the number of the status
code. Eventually, will move to separate exception types for each error code.
1 change: 1 addition & 0 deletions behance_python/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ENDPOINTS = {
'api': 'http://www.behance.net/v2',
'project': '/projects',
'user': '/users'
}

def url_join(*args):
Expand Down
56 changes: 44 additions & 12 deletions behance_python/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import urllib
import requests
from behance_python import ENDPOINTS, url_join
from project import Project
from user import User
from exceptions import BehanceException
from requests.exceptions import ConnectionError, HTTPError, Timeout, TooManyRedirects

# TODO: Searches not DRY. Refactor.
# TODO: Use property decorator on objects to avoid mixing methods and attributes

class API:
"""Base wrapper for the Behance api.
Expand All @@ -18,7 +23,7 @@ def get_project(self, project_id):

def project_search(self, *args, **kwargs):
"""Search for projects on Behance.
Takes list of plain text search terms, as well as key/value filters.
Takes any number of text search terms, as well as key/value filters.
Valid filters: [valid values]
sort: [featured_date, appreciations, views, comments, published_date]
Expand All @@ -33,20 +38,47 @@ def project_search(self, *args, **kwargs):
if len(args) == 0:
#Make sure user provides search terms...
raise BehanceException(000)
else:
#Build the URL
_base_url = url_join(ENDPOINTS['api'], ENDPOINTS['project'])
_terms = "+".join(urllib.quote(arg) for arg in args)
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&q=%s&%s' % (_base_url, self.auth_key, _terms, _filters)

#Build the URL
_base_url = url_join(ENDPOINTS['api'], ENDPOINTS['project'])
_terms = "+".join(arg for arg in args)
_filters = "&".join("%s=%s" % (k, v) for k, v in kwargs.items())
_url = '%s?api_key=%s&q=%s&%s' % (_base_url, self.auth_key, _terms, _filters)
#Get results from API
_results = requests.get(_url)

#Get results from API
_results = requests.get(_url)
#Parse results
if _results.status_code == 200:
return _results.json['projects']
else:
raise BehanceException(_results.status_code)
except (ConnectionError, HTTPError, Timeout, TooManyRedirects) as e:
raise e

#Parse results
if _results.status_code == 200:
return _results.json['projects']
def user_search(self, *args, **kwargs):
"""Search for users on Behance.
Takes any number of text search terms, as well as key/value filters
as supported by Behance API."""
try:
if len(args) == 0:
raise BehanceException(000)
else:
raise BehanceException(_results.status_code)
_base_url = url_join(ENDPOINTS['api'], ENDPOINTS['user'])
_terms = "+".join(urllib.quote(arg) for arg in args)
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&q=%s&%s' % (_base_url, self.auth_key, _terms, _filters)

#Get results from API
_results = requests.get(_url)

#Parse results
if _results.status_code == 200:
return _results.json['users']
else:
raise BehanceException(_results.status_code)
except (ConnectionError, HTTPError, Timeout, TooManyRedirects) as e:
raise e

def get_user(self, user_id):
return User(user_id, self.auth_key)
89 changes: 89 additions & 0 deletions behance_python/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import urllib
import requests
from behance_python import ENDPOINTS, url_join
from exceptions import BehanceException
from requests.exceptions import ConnectionError, HTTPError, Timeout, TooManyRedirects

# TODO: Very similar to Project class. Refactor and inherit common class.
# TODO: Should get_projects return project objects? How to do this with min overhead?

class User:

def __init__(self, user_id, auth_key):
self.user_id = user_id
self.auth_key = auth_key
self.base_url = url_join(ENDPOINTS['api'], ENDPOINTS['user'])

self._get_user_details()

def _add_property(self, name, value):
"""Helper function to dynamically add all the JSON data from API response
to the Project object."""
setattr(self.__class__, name, value)

def _get_api_data(self, url):
"""Internal helper to call API and handle exceptions"""
try:
_results = requests.get(url)

#Parse the data
if _results.status_code == 200:
return _results.json
else:
#If error from API, raise exception
raise BehanceException(_results.status_code)
except (ConnectionError, HTTPError, Timeout, TooManyRedirects) as e:
#If requests raises and exception
raise e

def _get_user_details(self):
#Build the URL
_url = url_join(self.base_url, str(self.user_id))
_url = "%s?api_key=%s" % (_url, self.auth_key)

#Call the API
#_results = requests.get(_url)
_results = self._get_api_data(_url)

for k, v in _results.items():
self._add_property(k, v)

def get_projects(self, **kwargs):
_base_url = url_join(self.base_url, self.user_id, 'projects')
if len(kwargs) > 0:
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&%s' % (_base_url, self.auth_key, _filters)
else:
_url = '%s?api_key=%s' % (_base_url, self.auth_key)

return self._get_api_data(_url)['projects']

def get_wips(self, **kwargs):
_base_url = url_join(self.base_url, self.user_id, 'wips')
if len(kwargs) > 0:
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&%s' % (_base_url, self.auth_key, _filters)
else:
_url = '%s?api_key=%s' % (_base_url, self.auth_key)

return self._get_api_data(_url)['wips']

def get_appreciations(self, **kwargs):
_base_url = url_join(self.base_url, self.user_id, 'appreciations')
if len(kwargs) > 0:
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&%s' % (_base_url, self.auth_key, _filters)
else:
_url = '%s?api_key=%s' % (_base_url, self.auth_key)

return self._get_api_data(_url)['appreciations']

def get_collections(self, **kwargs):
_base_url = url_join(self.base_url, self.user_id, 'collections')
if len(kwargs) > 0:
_filters = urllib.urlencode(kwargs)
_url = '%s?api_key=%s&%s' % (_base_url, self.auth_key, _filters)
else:
_url = '%s?api_key=%s' % (_base_url, self.auth_key)

return self._get_api_data(_url)['collections']

0 comments on commit 2bd60ec

Please sign in to comment.