Package install problem

0 views
Skip to first unread message

Anatoly Bubenkoff

unread,
Dec 28, 2009, 12:21:08 PM12/28/09
to opensocial-client-libraries
Hi,
i have problem using a package
created an issue http://code.google.com/p/opensocial-python-client/issues/detail?id=32
but looks no one checking issues...
i can post a patch...

Arne Roomann-Kurrik

unread,
Dec 28, 2009, 2:53:02 PM12/28/09
to opensocial-cl...@googlegroups.com
Hi Anatoly,

  Please post a patch, I'm happy to commit.

~Arne



--

You received this message because you are subscribed to the Google Groups "opensocial-client-libraries" group.
To post to this group, send email to opensocial-cl...@googlegroups.com.
To unsubscribe from this group, send email to opensocial-client-l...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/opensocial-client-libraries?hl=en.



Anatoly Bubenkov

unread,
Dec 28, 2009, 3:31:38 PM12/28/09
to opensocial-cl...@googlegroups.com
Arne Roomann-Kurrik wrote:
> Hi Anatoly,
>
> Please post a patch, I'm happy to commit.
>
> ~Arne
>
>
btw: interesting why do you use distutils instead of setuptools, it's
not so clear when using this package in buildout-based projects (like we
have)


--
Anatoly Bubenkov
+380(66)6358527
Zojax inc (http://zojax.com/)

opensocial.py.patch.txt

Anatoly Bubenkov

unread,
Dec 29, 2009, 7:35:10 AM12/29/09
to opensocial-cl...@googlegroups.com
Arne Roomann-Kurrik wrote:
> Hi Anatoly,
>
> Please post a patch, I'm happy to commit.
>
> ~Arne
>
>
sorry right patch is:
opensocial.py.patch.txt

Arne Roomann-Kurrik

unread,
Jan 6, 2010, 12:33:48 PM1/6/10
to opensocial-cl...@googlegroups.com
Thanks!  I've committed the patch and uploaded a new version of the library.

~Arne


--

You received this message because you are subscribed to the Google Groups "opensocial-client-libraries" group.
To post to this group, send email to opensocial-cl...@googlegroups.com.
To unsubscribe from this group, send email to opensocial-client-l...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/opensocial-client-libraries?hl=en.



Index: setup.py
===================================================================
--- setup.py    (revision 85)
+++ setup.py    (working copy)
@@ -28,6 +28,10 @@
    author_email='david...@google.com',
    license='Apache 2.0',
    url='http://code.google.com/p/opensocial-python-client',
-    packages=['opensocial', 'opensocial.oauth', 'opensocial.simplejson', 'opensocial.Crypto'],
-    package_dir={'opensocial': 'src/opensocial'}
+    packages=['opensocial', 'oauth', 'simplejson', 'Crypto', \
+              'Crypto.PublicKey', 'Crypto.Util'],
+    package_dir={'opensocial': 'src/opensocial',
+                 'oauth': 'src/opensocial/oauth',
+                 'simplejson': 'src/opensocial/simplejson',
+                 'Crypto': 'src/opensocial/Crypto',}
 )


Anatoly Bubenkov

unread,
Jan 7, 2010, 6:25:38 AM1/7/10
to opensocial-cl...@googlegroups.com
Arne Roomann-Kurrik wrote:
> Thanks! I've committed the patch and uploaded a new version of the
> library.
>
> ~Arne
patch to fix wrong imports
opensocial.py.patch.txt

Arne Roomann-Kurrik

unread,
Jan 20, 2010, 8:40:51 PM1/20/10
to opensocial-cl...@googlegroups.com
Hi Anatoly,

   The patch doesn't fix my SVN checkout, which appears to have broken for unit tests at some point.  I think there's a larger issue here, that we're including libraries in the distribution when we should just set dependencies and let end users install each dependency themselves.

   The reason the python library is set up this way is that it was originally meant to be mostly for App Engine use, which doesn't support Python package management.  We wanted App Engine developers to be able to unzip a directory into their project and start using the OpenSocial client without any additional work.  

   I think the approach I'd like to use is to remove the nested packages from SVN and host them in a directory named external/ or something similar.  The packaging scripts should be changed to build one App Engine specific distribution and another for installing as a Python system module.  The App Engine distribution could contain the appropriate libraries in its zip file and the system module would just declare dependencies.

  Thoughts on this proposal?

~Arne



Index: src/opensocial/request.py
===================================================================
--- src/opensocial/request.py   (revision 89)
+++ src/opensocial/request.py   (working copy)
@@ -27,14 +27,14 @@
 import data
 import http

-from opensocial import simplejson
+import simplejson


 def generate_uuid(*args):
  """Simple method for generating a unique identifier.
-
+
  Args: Any arguments used to help make this uuid more unique.
-
+
  Returns: A 128-bit hex identifier.

  """
@@ -47,45 +47,45 @@

 class Request(object):
  """Represents an OpenSocial request that can be processed via RPC or REST."""
-
+
  def __init__(self, rest_request, rpc_request, requestor=None):
    self.rest_request = rest_request
    self.rpc_request = rpc_request
    self.set_requestor(requestor)
-
+
  def get_requestor(self):
    """Get the requestor id for this request.
-
+
    Returns: The requestor's id.
-
+
    """
    return self.__requestor
-
+
  def set_requestor(self, id):
    """Set the requestor id for this request.
-
+
    This does not accept any keywords such as @me.
    TODO: Refactor the id check out of here, it feels wrong.
-
+
    Args:
      id: str The requestor's id.
-
+
    """
    if id and id[0] is not '@':
      self.__requestor = id
    else:
      self.__requestor = None
-
+
  def get_query_params(self):
    """Returns the query params string for this request."""
    query_params = {}
    if self.get_requestor():
      query_params['xoauth_requestor_id'] = self.get_requestor()
    return query_params
-
+
  def make_rest_request(self, url_base):
    """Creates a RESTful HTTP request.
-
+
    Args:
      url_base: str The base REST URL.

@@ -118,11 +118,11 @@
    def __init__(self, user_id, params=None):
        params = params or {}
        rest_request = RestRequestInfo('/'.join(('groups', user_id)),'GET', params )
-
+
        super(FetchGroupRequest, self).__init__(rest_request,
                                             None,
                                             user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
@@ -130,76 +130,76 @@
        Returns: a Collection of Person objects.
        """
        return data.Collection.parse_json(json, data.Group)
-
+
 class FetchAlbumRequest(Request):
    """A request for handling Album"""
-
+
    def __init__(self, user_id, albumid=None, params=None):
        params = params or {}
        if albumid !=  None:
            rest_request = RestRequestInfo('/'.join(('albums', user_id,'@self', albumid)),'GET', params )
        else:
            rest_request = RestRequestInfo('/'.join(('albums', user_id,'@self')),'GET', params )
-
+
        super(FetchAlbumRequest, self).__init__(rest_request,
                                             None,
                                             user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
        json: dict The JSON structure.
        Returns: a Collection of Person objects.
        """
-        json_list = json.get('album')
-
+        json_list = json.get('album')
+
        if json_list != None:
            """ this is  individual album """
            return data.Album(json_list)
-
+
        return data.Collection.parse_json(json, data.Album )
-
-
+
+
 class FetchMediaItemsRequest(Request):
    """A request for handling Album"""
-
+
    def __init__(self, user_id, albumid=None, mediaitemid=None, params=None):
        params = params or {}
        if mediaitemid !=  None:
            rest_request = RestRequestInfo('/'.join(('mediaitems', user_id,'@self', albumid, mediaitemid)),'GET', params )
        else:
            rest_request = RestRequestInfo('/'.join(('mediaitems', user_id,'@self', albumid)),'GET', params )
-
+
        super(FetchMediaItemsRequest, self).__init__(rest_request,
                                             None,
                                             user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
        json: dict The JSON structure.
        Returns: a Collection of Person objects.
        """
-        json_list = json.get('mediaItem')
-
+        json_list = json.get('mediaItem')
+
        if json_list != None:
            """ this is  individual album """
            return data.MediaItem(json_list)
-
+
        return data.Collection.parse_json(json, data.MediaItem )
-
-
+
+
 class FetchStatusMoodRequest(Request):
    """A request for handling Statusmoodcomments"""
-
+
    def __init__(self, user_id, params=None):
        params = params or {}
        rest_request = RestRequestInfo('/'.join(('statusmood', user_id,'@self')),'GET', params )
-
+
        super(FetchStatusMoodRequest, self).__init__(rest_request,
                                                     None,
                                                     user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
@@ -210,15 +210,15 @@

 class FetchStatusMoodCommentsRequest(Request):
    """A request for handling StatusmoodcommentsRequests"""
-
+
    def __init__(self, user_id, params=None):
        params = params or {}
        rest_request = RestRequestInfo('/'.join(('statusMoodComments', user_id,'@self')),'GET', params )
-
+
        super(FetchStatusMoodCommentsRequest, self).__init__(rest_request,
                                                     None,
                                                     user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
@@ -226,29 +226,29 @@
        Returns: a Collection of statusmoodcomments objects objects.
        """
        return data.Collection.parse_json(json, data.StatusMoodComments)
-
-
+
+
 class FetchProfileCommentsRequest(Request):
    """A request for handling profile comments"""
-
+
    def __init__(self, user_id, params=None):
        params = params or {}
        rest_request = RestRequestInfo('/'.join(('profilecomments', user_id,'@self')),'GET', params )
        super(FetchProfileCommentsRequest, self).__init__(rest_request,
                                                     None,
                                                     user_id)
-
+
    def process_json(self, json):
        """Construct the appropriate OpenSocial object from a JSON dict.
        Args:
        json: dict The JSON structure.
        Returns: a Collection of statusmoodcomments objects objects.
        """
-        return data.Collection.parse_json(json, data.ProfileComments)
+        return data.Collection.parse_json(json, data.ProfileComments)

-class FetchPeopleRequest(Request):
+class FetchPeopleRequest(Request):
  """A request for handling fetching a collection of people."""
-
+
  def __init__(self, user_id, group_id, fields=None, params=None):
    params = params or {}
    if fields:
@@ -262,19 +262,19 @@
    super(FetchPeopleRequest, self).__init__(rest_request,
                                             rpc_request,
                                             user_id)
-
+
  def process_json(self, json):
    """Construct the appropriate OpenSocial object from a JSON dict.
-
+
    Args:
      json: dict The JSON structure.
-
+
    Returns: a Collection of Person objects.

    """
    return data.Collection.parse_json(json, data.Person)

-
+
 class FetchPersonRequest(FetchPeopleRequest):
  """A request for handling fetching a single person by id."""

@@ -286,10 +286,10 @@

  def process_json(self, json):
    """Construct the appropriate OpenSocial object from a JSON dict.
-
+
    Args:
      json: dict The JSON structure.
-
+
    Returns: A Person object.

    """
@@ -299,15 +299,15 @@
 class FetchAppDataRequest(Request):
  """A request for handling fetching app data."""

-  def __init__(self, user_id, group_id, app_id='@app', fields=None,
+  def __init__(self, user_id, group_id, app_id='@app', fields=None,
               params=None):
    params = params or {}
    if fields:
      params['fields'] = ','.join(fields)
-
+
    rest_path = '/'.join(('appdata', user_id, group_id, app_id))
    rest_request = RestRequestInfo(rest_path, params=params)
-
+
    # TODO: Handle REST fields.
    params.update({'userId': user_id,
                   'groupId': group_id,
@@ -320,10 +320,10 @@

  def process_json(self, json):
    """Construct the appropriate OpenSocial object from a JSON dict.
-
+
    Args:
      json: dict The JSON structure.
-
+
    Returns: An AppData object.

    """
@@ -336,12 +336,12 @@
 class UpdateAppDataRequest(Request):
  """A request for handling updating app data."""

-  def __init__(self, user_id, group_id, app_id='@app', fields=None, data={},
+  def __init__(self, user_id, group_id, app_id='@app', fields=None, data={},
               params=None):
    params = params or {}
    if fields:
      params['fields'] = ','.join(fields)
-    else:
+    else:
      params['fields'] = ','.join(data.keys())

    params['data'] = data
@@ -362,7 +362,7 @@
 class DeleteAppDataRequest(Request):
  """A request for handling deleting app data."""

-  def __init__(self, user_id, group_id, app_id='@app', fields=None,
+  def __init__(self, user_id, group_id, app_id='@app', fields=None,
               params=None):
    params = params or {}
    if fields:
@@ -386,7 +386,7 @@

 class CreateNotificationRequest(Request):
    """ A request for creating an Notification. """
-    def __init__(self, user_id, recipients, mediaitems = None, templateParameters = None,
+    def __init__(self, user_id, recipients, mediaitems = None, templateParameters = None,
               params=None):

        params = params or {}
@@ -397,19 +397,19 @@
                itemdict = {}
                itemdict['msMediaItemUri'] = mediaitem;
                itemlist.append(itemdict);
-
+
            bodycontent['mediaItems'] = itemlist
            bodycontent['recipientIds'] = recipients
            bodycontent['templateParameters'] = templateParameters
-
-        #if user_id != "@me":
+
+        #if user_id != "@me":
        #    params['xoauth_requestor_id'] = user_id;
-
+
        rest_request = RestRequestInfo('/'.join(('notifications', user_id,'@self')),'POST', params, bodycontent, False)
        super(CreateNotificationRequest, self).__init__(rest_request,
                                                  None,
                                                  user_id)
-
+
    def process_json(self, json):
        return json

@@ -419,13 +419,13 @@
    rest_request = RestRequestInfo('/'.join(('albums', user_id,'@self')),'POST', params, body , False)
    super(CreateAlbumRequest, self ).__init__(rest_request, None, user_id)
    pass
-
+
  def process_json(self, json):
    return json

 class CreateActivityRequest(Request):
  """ A request for creating an activity. """
-  def __init__(self, user_id, activity, group_id='@self', app_id='@app',
+  def __init__(self, user_id, activity, group_id='@self', app_id='@app',
               params=None):
    params = params or {}
    params['activity'] = activity
@@ -438,7 +438,7 @@
    super(CreateActivityRequest, self).__init__(None,
                                              rpc_request,
                                              user_id)
-
+
  def process_json(self, json):
    return json

@@ -456,11 +456,11 @@
      rest_request = RestRequestInfo('/'.join(('activities', user_id,'@self', app_id)),'GET', params)
    else:
      rest_request = RestRequestInfo('/'.join(('activities', user_id,'@self')),'GET', params)
-
+
    super(FetchActivityRequest, self).__init__(rest_request,
                                              rpc_request,
                                              user_id)
-
+
  def process_json(self, json):
    return data.Collection.parse_json(json, data.Activity)

@@ -477,10 +477,10 @@

  def make_http_request(self, url_base, query_params=None):
    """Generates a http.Request object for the UrlFetch interface.
-
+
    Args:
      url_base: str The base REST URL.
-
+
    Returns: The http.Request object.

    """
@@ -537,10 +537,10 @@
    self.method = method
    self.params = params
    self.id = id or generate_uuid(method)
-
+
  def get_rpc_body(self):
    """Creates the JSON dict structure for thie RPC request.
-
+
    Returns: dict The JSON body for this RPC.

    """
@@ -554,14 +554,14 @@

 class RequestBatch(object):
  """This class will manage the batching of requests."""
-
+
  def __init__(self):
    self.requests = {}
    self.data = {}
-
+
  def add_request(self, key, request):
    """Adds a request to this batch.
-
+
    Args:
      key: str A unique key to pair with the result of this request.
      request: obj The request object.
@@ -573,7 +573,7 @@

  def get(self, key):
    """Get the result value for a given request key.
-
+
    Args:
      key: str The key to retrieve.

@@ -582,7 +582,7 @@

  def send(self, container):
    """Execute the batch with the specified container.
-
+
    Args:
      container: The container to execute this batch on.

Index: src/opensocial/validator.py
===================================================================
--- src/opensocial/validator.py (revision 89)
+++ src/opensocial/validator.py (working copy)
@@ -23,8 +23,8 @@
 import hmac
 import logging

-from opensocial.Crypto.PublicKey import RSA
-from opensocial.Crypto.Util import number
+from Crypto.PublicKey import RSA
+from Crypto.Util import number

 class RequestValidator(object):
  def get_signature_base_string(self, method, url, params):
@@ -36,7 +36,7 @@
      url: string The fully-qualified url of the request.
      params: string Parameters used to sign the request.  Should be a merged
          set of all querystring, form-urlencoded POST body, and header params.
-
+
    Returns: string A signature base string as defined by the OAuth spec.
    """
    encoded_params = {}
@@ -44,8 +44,8 @@
      encoded_params[key] = value.encode('utf-8', 'ignore')

    oauth_request = oauth.OAuthRequest(
-        http_method=method.upper(),
-        http_url=url,
+        http_method=method.upper(),
+        http_url=url,
        parameters=encoded_params)

    base_str = '&'.join((
@@ -54,17 +54,17 @@
        oauth.escape(oauth_request.get_normalized_parameters())))

    return base_str
-
+
  def validate(self, method, url, params):
    """
    Determines the validity of an OAuth-signed HTTP request.
-
+
    Args:
      method: string The HTTP method used for signing the request.
      url: string The fully-qualified url of the request.
      params: string Parameters used to sign the request.  Should be a merged
          set of all querystring, form-urlencoded POST body, and header params.
-
+
    Returns: bool True if the request validated, False otherwise.
    """
    raise NotImplementedError('RequestValidator must be subclassed.')
@@ -74,10 +74,10 @@
  def __init__(self, public_key_str, exponent=65537):
    """
    Creates a validator based off of the RSA-SHA1 signing mechanism.
-
+
    Args:
-      public_key_str: string The RSA public key modulus, expressed in hex
-          format.  Typically, this will look something like:
+      public_key_str: string The RSA public key modulus, expressed in hex
+          format.  Typically, this will look something like:
                0x00b1e057678343866db89d7dec2518
                99261bf2f5e0d95f5d868f81d600c9a1
                01c9e6da20606290228308551ed3acf9
@@ -87,45 +87,45 @@
                efb45d26694caf4f26b9765b9f656652
                45524de957e8c547c358781fdfb68ec0
                56d1
-          A list of such values can be found at
+          A list of such values can be found at
          https://opensocialresources.appspot.com/certificates/
      exponent: int The RSA public key exponent.
    """
    public_key_long = long(public_key_str, 16)
    self.public_key = RSA.construct((public_key_long, exponent))
-
+
  def validate(self, method, url, params):
    """
    Determines the validity of an OAuth-signed HTTP request.
-
+
    Args:
      method: string The HTTP method used for signing the request.
      url: string The fully-qualified url of the request.
      params: string Parameters used to sign the request.  Should be a merged
          set of all querystring, form-urlencoded POST body, and header params.
-
+
    Returns: bool True if the request validated, False otherwise.
    """
    base_string = self.get_signature_base_string(method, url, params)
    local_hash = hashlib.sha1(base_string).digest()
-
+
    if not params.has_key("oauth_signature"):
      return False
-
+
    try:
      encoded_remote_signature = urllib.unquote(params["oauth_signature"])
      remote_signature = base64.decodestring(encoded_remote_signature)
      remote_hash = self.public_key.encrypt(remote_signature, '')[0][-20:]
    except:
      return False
-
+
    return local_hash == remote_hash

 class HmacSha1Validator(RequestValidator):
  def __init__(self, key):
    """
    Creates a validator based off of the HMAC-SHA1 signing mechanism.
-
+
    Args:
      key: string The shared secret key used to sign this request.  Typically,
          this value will be shared with the owner of an application at the
@@ -133,17 +133,17 @@
      exponent: int The RSA public key exponent.
    """
    self.hmac_key = '%s&' % oauth.escape(key)
-
+
  def validate(self, method, url, params):
    """
    Determines the validity of an OAuth-signed HTTP request.
-
+
    Args:
      method: string The HTTP method used for signing the request.
      url: string The fully-qualified url of the request.
      params: string Parameters used to sign the request.  Should be a merged
          set of all querystring, form-urlencoded POST body, and header params.
-
+
    Returns: bool True if the request validated, False otherwise.
    """
    base_string = self.get_signature_base_string(method, url, params)
@@ -159,5 +159,5 @@
      return False

    return local_hash == remote_hash
-
-
+
+

Anatoly Bubenkov

unread,
Jan 21, 2010, 3:03:29 AM1/21/10
to opensocial-cl...@googlegroups.com
Arne Roomann-Kurrik wrote:
> Hi Anatoly,
>
> The patch doesn't fix my SVN checkout, which appears to have broken
> for unit tests at some point. I think there's a larger issue here,
> that we're including libraries in the distribution when we should just
> set dependencies and let end users install each dependency themselves.
tests were broken before the patch?
i agree subpackages can be published separately, but then we need to
publish them somewhere...
Reply all
Reply to author
Forward
0 new messages