HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Mutual friends finder written in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
writtenfinderpythonmutualfriends

Problem

I've written a server/client tool which can "check the Six degrees of separation theory" in Russian social network VK.com. Client sends task (which contains two VK IDs) and Server tries to find all connections between these two IDs. I've also written a simple HTTP client just to practice working with sockets.

HTTPClient.py:

import socket
import re

def get(host, port, address):
    s = socket.socket()
    s.connect((host,port))
    s.sendall("GET %s HTTP/1.0\nHost: %s\n\n" % (address, host))
    answer = ""
    symbol = s.recv(1024576)
    while symbol != '':
        answer += symbol
        symbol = s.recv(1024576)
    s.close()
    answer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
    return answer


VKApi.py:

```
import HTTPClient
import json
import re
import types
import md5
import time

class BaseAPIException(Exception):

def __init__(self, text=''):
Exception.__init__(self,text)

class LoginException(BaseAPIException):
pass

class MethodExecutionException(BaseAPIException):
pass

class VKApi:

def __init__(self,appId,scope=[],callbackUrl='https://oauth.vk.com/blank.html'):
self.appId = appId
if ( not isinstance(scope,types.ListType)): raise Exception("Wrong args")
scope.append('nohttps')
self.scope = ','.join(scope)
self.callbackUrl=callbackUrl
self.isLoggedIn = False
self.callsCount = 0

def getAuthorizeLink(self):
return "https://oauth.vk.com/authorize?client_id=%s&scope=%s&redirect_uri=%s&display=page&v=5.21&response_type=token" % \
(self.appId, self.scope, self.callbackUrl)

def login(self, link):
tokenRegExp = re.search('access_token=(.*?)(&|$)',link)
if tokenRegExp == None: raise LoginException('No token found')
self.token = tokenRegExp.group(1)
secretRegExp = re.search('secret=(.*?)(&|$)',link)
if secretRegExp == None: raise LoginException('No secret found')
self.secret = s

Solution

That's quite a lot of code to review. I'll review only some parts.

HTTPClient.py

Instead of using magic number 1024576 twice,
it's better to give it a meaningful name and put it near the top of the file where it's easy to see, for example:

BUFSIZE = 1024576


In this piece of code:

symbol = s.recv(1024576)
while symbol != '':
    answer += symbol
    symbol = s.recv(1024576)


The name "symbol" is not great. A symbol usually suggests a single character, but here it's an entire buffer. And instead of checking for symbol != '', a more Pythonic way is to do not symbol. Finally, the statement symbol = s.recv(1024576) is repeated twice. A better way to write the same thing:

while True:
    buf = s.recv(BUFSIZE)
    if not buf:
        break
    answer += buf


At the end of the method you strip the header from the response like this:

answer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
return answer


In my tests, some sites don't actually return a proper header, the expression will match nothing, and so the .group(1) will raise an error. To make it more robust, I recommend to rewrite like this:

return re.sub(".*\r\n\r\n", '', answer, flags=re.DOTALL)


Exception handling

This exception class can be simplified:

class BaseAPIException(Exception):
    def __init__(self, text=''):
        Exception.__init__(self,text)


This is equivalent:

class BaseAPIException(Exception):
    pass


Non-standard formatting

There's an official coding style guide called PEP8. You are violating it everywhere, making your code harder to read than it needs to be. For example:

def __init__(self,appId,scope=[],callbackUrl='https://oauth.vk.com/blank.html'):
    self.appId = appId
    if ( not isinstance(scope,types.ListType)): raise Exception("Wrong args")
    scope.append('nohttps')
    self.scope = ','.join(scope)
    self.callbackUrl=callbackUrl
    self.isLoggedIn = False
    self.callsCount = 0


This should be formatted like this to conform to the standard:

def __init__(self, appId, scope=[], callbackUrl='https://oauth.vk.com/blank.html'):
    self.appId = appId
    if not isinstance(scope, types.ListType):
        raise Exception("Wrong args")
    scope.append('nohttps')
    self.scope = ','.join(scope)
    self.callbackUrl = callbackUrl
    self.isLoggedIn = False
    self.callsCount = 0


Your code is full of this kind of violations. There is a command line utility called pep8, which you can install easily with pip install pep8, which can tell you all the violations.

Checking for None

Instead of this:

if tokenRegExp == None:


The recommended way is this:

if tokenRegExp is None:


Or even simpler:

if not tokenRegExp:

Code Snippets

BUFSIZE = 1024576
symbol = s.recv(1024576)
while symbol != '':
    answer += symbol
    symbol = s.recv(1024576)
while True:
    buf = s.recv(BUFSIZE)
    if not buf:
        break
    answer += buf
answer = re.search("\r\n\r\n(.+)", answer, re.DOTALL).group(1)
return answer
return re.sub(".*\r\n\r\n", '', answer, flags=re.DOTALL)

Context

StackExchange Code Review Q#60886, answer score: 3

Revisions (0)

No revisions yet.