Manual:API Python3: Difference between revisions
Jump to navigation
Jump to search
API client example in Python3 |
m make this readable |
||
Line 1: | Line 1: | ||
#!/usr/bin/python | #!/usr/bin/python | ||
import sys, posix, time, binascii, socket, select | import sys, posix, time, binascii, socket, select | ||
import hashlib | import hashlib | ||
class ApiRos: | class ApiRos: | ||
"Routeros api" | "Routeros api" | ||
def __init__(self, sk): | def __init__(self, sk): | ||
self.sk = sk | self.sk = sk | ||
self.currenttag = 0 | self.currenttag = 0 | ||
def login(self, username, pwd): | def login(self, username, pwd): | ||
for repl, attrs in self.talk(["/login"]): | for repl, attrs in self.talk(["/login"]): | ||
Line 19: | Line 19: | ||
self.talk(["/login", "=name=" + username, | self.talk(["/login", "=name=" + username, | ||
"=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ]) | "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ]) | ||
def talk(self, words): | def talk(self, words): | ||
if self.writeSentence(words) == 0: return | if self.writeSentence(words) == 0: return | ||
Line 36: | Line 36: | ||
r.append((reply, attrs)) | r.append((reply, attrs)) | ||
if reply == '!done': return r | if reply == '!done': return r | ||
def writeSentence(self, words): | def writeSentence(self, words): | ||
ret = 0 | ret = 0 | ||
Line 44: | Line 44: | ||
self.writeWord('') | self.writeWord('') | ||
return ret | return ret | ||
def readSentence(self): | def readSentence(self): | ||
r = [] | r = [] | ||
Line 56: | Line 56: | ||
self.writeLen(len(w)) | self.writeLen(len(w)) | ||
self.writeStr(w) | self.writeStr(w) | ||
def readWord(self): | def readWord(self): | ||
ret = self.readStr(self.readLen()) | ret = self.readStr(self.readLen()) | ||
print((">>> " + ret)) | print((">>> " + ret)) | ||
return ret | return ret | ||
def writeLen(self, l): | def writeLen(self, l): | ||
if l < 0x80: | if l < 0x80: | ||
Line 86: | Line 86: | ||
self.writeStr(chr((l >> 8) & 0xFF)) | self.writeStr(chr((l >> 8) & 0xFF)) | ||
self.writeStr(chr(l & 0xFF)) | self.writeStr(chr(l & 0xFF)) | ||
def readLen(self): | def readLen(self): | ||
c = ord(self.readStr(1)) | c = ord(self.readStr(1)) | ||
Line 118: | Line 118: | ||
c += ord(self.readStr(1)) | c += ord(self.readStr(1)) | ||
return c | return c | ||
def writeStr(self, str): | def writeStr(self, str): | ||
n = 0; | n = 0; | ||
Line 125: | Line 125: | ||
if r == 0: raise RuntimeError("connection closed by remote end") | if r == 0: raise RuntimeError("connection closed by remote end") | ||
n += r | n += r | ||
def readStr(self, length): | def readStr(self, length): | ||
ret = '' | ret = '' | ||
Line 133: | Line 133: | ||
ret += s | ret += s | ||
return ret | return ret | ||
def main(): | def main(): | ||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
s.connect((sys.argv[1], 8728)) | s.connect((sys.argv[1], 8728)) | ||
apiros = ApiRos(s); | apiros = ApiRos(s); | ||
apiros.login(sys.argv[2], sys.argv[3]); | apiros.login(sys.argv[2], sys.argv[3]); | ||
inputsentence = [] | inputsentence = [] | ||
while 1: | while 1: | ||
r = select.select([s, sys.stdin], [], [], None) | r = select.select([s, sys.stdin], [], [], None) | ||
Line 147: | Line 147: | ||
# something to read in socket, read sentence | # something to read in socket, read sentence | ||
x = apiros.readSentence() | x = apiros.readSentence() | ||
if sys.stdin in r[0]: | if sys.stdin in r[0]: | ||
# read line from input and strip off newline | # read line from input and strip off newline | ||
l = sys.stdin.readline() | l = sys.stdin.readline() | ||
l = l[:-1] | l = l[:-1] | ||
# if empty line, send sentence and start with new | # if empty line, send sentence and start with new | ||
# otherwise append to input sentence | # otherwise append to input sentence | ||
Line 160: | Line 160: | ||
else: | else: | ||
inputsentence.append(l) | inputsentence.append(l) | ||
if __name__ == '__main__': | if __name__ == '__main__': | ||
main() | main() |
Revision as of 13:13, 3 August 2011
#!/usr/bin/python import sys, posix, time, binascii, socket, select import hashlib class ApiRos: "Routeros api" def __init__(self, sk): self.sk = sk self.currenttag = 0 def login(self, username, pwd): for repl, attrs in self.talk(["/login"]): chal = binascii.unhexlify((attrs['=ret']).encode('UTF-8')) md = hashlib.md5() md.update(b'\x00') md.update(pwd.encode('UTF-8')) md.update(chal) self.talk(["/login", "=name=" + username, "=response=00" + binascii.hexlify(md.digest()).decode('UTF-8') ]) def talk(self, words): if self.writeSentence(words) == 0: return r = [] while 1: i = self.readSentence(); if len(i) == 0: continue reply = i[0] attrs = {} for w in i[1:]: j = w.find('=', 1) if (j == -1): attrs[w] = else: attrs[w[:j]] = w[j+1:] r.append((reply, attrs)) if reply == '!done': return r def writeSentence(self, words): ret = 0 for w in words: self.writeWord(w) ret += 1 self.writeWord() return ret def readSentence(self): r = [] while 1: w = self.readWord() if w == : return r r.append(w) def writeWord(self, w): print(("<<< " + w)) self.writeLen(len(w)) self.writeStr(w) def readWord(self): ret = self.readStr(self.readLen()) print((">>> " + ret)) return ret def writeLen(self, l): if l < 0x80: self.writeStr(chr(l)) elif l < 0x4000: l |= 0x8000 self.writeStr(chr((l >> 8) & 0xFF)) self.writeStr(chr(l & 0xFF)) elif l < 0x200000: l |= 0xC00000 self.writeStr(chr((l >> 16) & 0xFF)) self.writeStr(chr((l >> 8) & 0xFF)) self.writeStr(chr(l & 0xFF)) elif l < 0x10000000: l |= 0xE0000000 self.writeStr(chr((l >> 24) & 0xFF)) self.writeStr(chr((l >> 16) & 0xFF)) self.writeStr(chr((l >> 8) & 0xFF)) self.writeStr(chr(l & 0xFF)) else: self.writeStr(chr(0xF0)) self.writeStr(chr((l >> 24) & 0xFF)) self.writeStr(chr((l >> 16) & 0xFF)) self.writeStr(chr((l >> 8) & 0xFF)) self.writeStr(chr(l & 0xFF)) def readLen(self): c = ord(self.readStr(1)) if (c & 0x80) == 0x00: pass elif (c & 0xC0) == 0x80: c &= ~0xC0 c <<= 8 c += ord(self.readStr(1)) elif (c & 0xE0) == 0xC0: c &= ~0xE0 c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) elif (c & 0xF0) == 0xE0: c &= ~0xF0 c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) elif (c & 0xF8) == 0xF0: c = ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) c <<= 8 c += ord(self.readStr(1)) return c def writeStr(self, str): n = 0; while n < len(str): r = self.sk.send(bytes(str[n:], 'UTF-8')) if r == 0: raise RuntimeError("connection closed by remote end") n += r def readStr(self, length): ret = while len(ret) < length: s = self.sk.recv(length - len(ret)).decode('UTF-8') if s == : raise RuntimeError("connection closed by remote end") ret += s return ret def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((sys.argv[1], 8728)) apiros = ApiRos(s); apiros.login(sys.argv[2], sys.argv[3]); inputsentence = [] while 1: r = select.select([s, sys.stdin], [], [], None) if s in r[0]: # something to read in socket, read sentence x = apiros.readSentence() if sys.stdin in r[0]: # read line from input and strip off newline l = sys.stdin.readline() l = l[:-1] # if empty line, send sentence and start with new # otherwise append to input sentence if l == : apiros.writeSentence(inputsentence) inputsentence = [] else: inputsentence.append(l) if __name__ == '__main__': main()