Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions contrib/tajo-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# python-tajo-rest-client
Python Tajo Rest Client Module

# requirements
pip install httplib2
42 changes: 42 additions & 0 deletions contrib/tajo-python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from setuptools import setup, find_packages
import sys

DESCRIPTION = """python tajo rest client
"""

install_requires = ["httplib2"]

setup(
name="tajo-rest-client",
version="0.0.1",
description="a Python implementation of Tajo Rest Client",
long_description=DESCRIPTION,
url='http://github.com/charsyam/python-tajo-rest-client/',
author='DaeMyung Kang',
author_email='charsyam@gmail.com',
classifiers=[
'Intended Audience :: Developers',
'License :: OSI Approved :: Apache Software License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Software Development :: Libraries :: Python Modules'],
packages=find_packages('src'),
package_dir={'': 'src'},
install_requires=install_requires,
test_suite='',
)
14 changes: 14 additions & 0 deletions contrib/tajo-python/src/tajo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
86 changes: 86 additions & 0 deletions contrib/tajo-python/src/tajo/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tajo.error import *
from tajo.py3 import httplib, PY3

try:
import simplejson as json
except ImportError:
import json

class TajoObject(object):
def __init__(self):
pass

@staticmethod
def create(headers, content):
raise NotImplementedMethodError("object create error")


class TajoRequest(object):
object_cls = None
ok_status = [httplib.OK]

def __init__(self):
pass

def method(self):
return "GET"

def uri(self):
raise NotImplementedMethodError("uri")

def params(self):
raise NotImplementedMethodError("params")

def headers(self):
raise NotImplementedMethodError("headers")

def object_cls(self):
if self.object_cls is None:
raise NotImplementedMethodError("cls")

return self.object_cls

def check_status(self, headers, contents):
status = int(headers["status"])
if status not in self.ok_status:
msg = status
if PY3:
contents = contents.decode('utf-8')

c = json.loads(contents)
if 'message' in c:
msg = "%s %s"%(status, c["message"])

if headers["status"][0] == '4':
raise InvalidRequestError(msg)
if headers["status"][0] == '5':
raise InternalError(msg)

def request(self, conn):
headers, contents = conn._request(self.method(), self.uri(), self.params())
self.check_status(headers, contents)
return self.object_cls.create(headers, contents)


class TajoPostRequest(TajoRequest):
def method(self):
return "POST"

class TajoDeleteRequest(TajoRequest):
def method(self):
return "DELETE"
166 changes: 166 additions & 0 deletions contrib/tajo-python/src/tajo/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tajo.session import TajoSessionRequest, TajoSession
from tajo.query import TajoQueryRequest, TajoQuery
from tajo.queryid import QueryId
from tajo.queries import TajoQueriesRequest
from tajo.querystatus import TajoQueryStatusRequest, TajoQueryStatus
from tajo.resultsetinfo import TajoResultSetInfoRequest, TajoResultSetInfo
from tajo.resultset import TajoMemoryResultSetRequest, TajoMemoryResultSet
from tajo.fetchresultset import TajoFetchResultSet
from tajo.connection import TajoConnection
from tajo.cluster import TajoCluster, TajoClusterRequest
from tajo.querystate import QueryState
from tajo.database import TajoDatabasesRequest, TajoDatabases, TajoDatabaseRequest, TajoDatabase
from tajo.database import TajoCreateDatabaseRequest, TajoDeleteDatabaseRequest
from tajo.tables import TajoTablesRequest, TajoTableRequest
from tajo.functions import TajoFunctionsRequest
from tajo.error import *

import time

class TajoClient(object):
def __init__(self, base = 'http://127.0.0.1:26880/rest/',
username = 'tajo', database = 'default',
rowNum = 1024):
self.clear()
self.base = base
self.username = username
self.database = database
self.rowNum = rowNum
self.conn = TajoConnection(self.base)
self.session = self.create_session()

def clear(self):
self.base = None
self.username = "tajo"
self.database = "default"
self.rowNum = 1024
self.conn = None
self.session = None

def create_session(self):
request = TajoSessionRequest(self.username, self.database)
self.session = request.request(self.conn)
self.conn.add_header("X-Tajo-Session", str(self.session))

def execute_query(self, query):
req = TajoQueryRequest(query)
return req.request(self.conn)

def is_null_query_id(self, query_id):
ret = False

if query_id.query_id == QueryId.NULL_QUERY_ID:
ret = True

return ret

def queries(self):
req = TajoQueriesRequest(self.database)
return req.request(self.conn)

def query_status(self, query_id):
if query_id.completed:
return TajoQueryStatus(query_id.status)
elif self.is_null_query_id(query_id):
raise NullQueryIdError()

req = TajoQueryStatusRequest(query_id, self.base)
return req.request(self.conn)

def query_resultset_info(self, query_id):
if self.is_null_query_id(query_id):
raise NullQueryIdError()

if query_id.completed:
return TajoResultSetInfo(None, query_id.schema)

req = TajoResultSetInfoRequest(query_id, self.base)
return req.request(self.conn)

def query_resultset(self, resultsetinfo, count = 100):
req = TajoMemoryResultSetRequest(resultsetinfo, self.base, count)
return req.request(self.conn)

def fetch(self, query_id, fetch_row_num = 100):
resultset_info = self.query_resultset_info(query_id)
return TajoFetchResultSet(self, query_id, resultset_info, fetch_row_num)

def create_nullresultset(self, queryId):
return TajoMemoryResultSet(None, True, 0, 0, None)

def execute_query_wait_result(self, query):
query_id = self.execute_query(query)
if self.is_null_query_id(query_id):
return self.create_nullresultset(query_id)

status = self.query_status(query_id)
while self.is_query_complete(status.state) == False:
time.sleep(0.1)
status = query_status(query_id)

if status.state == QueryState.QUERY_SUCCEEDED:
return self.fetch(query_id)

return self.create_nullresultset(query_id)

def is_query_waiting_for_schedule(self, state):
return state == QueryState.QUERY_NOT_ASSIGNED or \
state == QueryState.QUERY_MASTER_INIT or \
state == QueryState.QUERY_MASTER_LAUNCHED

def is_query_inited(self, state):
return state == QueryState.QUERY_NEW

def is_query_running(self, state):
return self.is_query_inited(state) or (state == QueryState.QUERY_RUNNING)

def is_query_complete(self, state):
return self.is_query_waiting_for_schedule(state) == False and \
self.is_query_running(state) == False

def cluster_info(self):
req = TajoClusterRequest()
return req.request(self.conn)

def databases(self):
req = TajoDatabasesRequest()
return req.request(self.conn)

def database_info(self, database_name):
req = TajoDatabaseRequest(database_name)
return req.request(self.conn)

def create_database(self, database_name):
req = TajoCreateDatabaseRequest(database_name)
return req.request(self.conn)

def delete_database(self, database_name):
req = TajoDeleteDatabaseRequest(database_name)
return req.request(self.conn)

def tables(self, database_name):
req = TajoTablesRequest(database_name)
return req.request(self.conn)

def table(self, database_name, table_name):
req = TajoTableRequest(database_name, table_name)
return req.request(self.conn)

def functions(self):
req = TajoFunctionsRequest()
return req.request(self.conn)
57 changes: 57 additions & 0 deletions contrib/tajo-python/src/tajo/cluster.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tajo.error import InvalidStatusError
from tajo.base import TajoRequest, TajoObject
from tajo.py3 import httplib, PY3

try:
import simplejson as json
except ImportError:
import json

class TajoCluster(TajoObject):
def __init__(self, objs):
self.objs = objs

def __repr__(self):
return str(self.objs)

@staticmethod
def create(headers, content):
if PY3:
content = content.decode('utf-8')

return TajoCluster(content)


class TajoClusterRequest(TajoRequest):
object_cls = TajoCluster
ok_status = [httplib.OK]

def __init__(self):
self.objs = None

def uri(self):
return "cluster"

def headers(self):
return None

def params(self):
return None

def cls(self):
return self.object_cls
20 changes: 20 additions & 0 deletions contrib/tajo-python/src/tajo/column.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

class Column:
def __init__(self, name, datatype, length = 1):
self.name = name
self.datatype = datatype.upper()
self.length = length
Loading