rabin 7 years ago
commit
31e4603ed2

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+.DS_Store
+*.pyc
+runtime/upload/*
+runtime/camera/*
+runtime/postgresql/*

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# jupyter-mysql-kernel

+ 6 - 0
jupyter-mysql-kernel/__init__.py

@@ -0,0 +1,6 @@
+"""
+	jupyter-mysql-kernel
+	author:rabin
+"""
+
+from .kernel import __version__

+ 7 - 0
jupyter-mysql-kernel/__main__.py

@@ -0,0 +1,7 @@
+"""
+	jupyter-mysql-kernel
+	author:rabin
+"""
+from ipykernel.kernelapp import IPKernelApp
+from .kernel import MysqlKernel
+IPKernelApp.launch_instance(kernel_class=MysqlKernel)

+ 70 - 0
jupyter-mysql-kernel/install.py

@@ -0,0 +1,70 @@
+"""
+    jupyter-mysql-kernel
+    author:rabin
+"""
+import json
+import os
+import sys
+import argparse
+
+from jupyter_client.kernelspec import KernelSpecManager
+from IPython.utils.tempdir import TemporaryDirectory
+
+kernel_json = {"argv":[sys.executable,"-m","jupyter-mysql-kernel", "-f", "{connection_file}"],
+ "display_name":"Mysql",
+ "language":"mysql"
+}
+
+def install_my_kernel_spec(user=True, prefix=None):
+    with TemporaryDirectory() as td:
+        os.chmod(td, 0o755)
+        with open(os.path.join(td, 'kernel.json'), 'w') as f:
+            json.dump(kernel_json, f, sort_keys=True)
+
+        print('Installing IPython kernel spec')
+        KernelSpecManager().install_kernel_spec(td, 'mysql', user=user, replace=True, prefix=prefix)
+
+def _is_root():
+    try:
+        return os.geteuid() == 0
+    except AttributeError:
+        return False
+
+def main(argv=None):
+    parser = argparse.ArgumentParser(
+        description='Install KernelSpec for Mysql Kernel'
+    )
+    prefix_locations = parser.add_mutually_exclusive_group()
+
+    prefix_locations.add_argument(
+        '--user',
+        help='Install KernelSpec in user homedirectory',
+        action='store_true'
+    )
+    prefix_locations.add_argument(
+        '--sys-prefix',
+        help='Install KernelSpec in sys.prefix. Useful in conda / virtualenv',
+        action='store_true',
+        dest='sys_prefix'
+    )
+    prefix_locations.add_argument(
+        '--prefix',
+        help='Install KernelSpec in this prefix',
+        default=None
+    )
+
+    args = parser.parse_args(argv)
+
+    user = False
+    prefix = None
+    if args.sys_prefix:
+        prefix = sys.prefix
+    elif args.prefix:
+        prefix = args.prefix
+    elif args.user or not _is_root():
+        user = True
+
+    install_my_kernel_spec(user=user, prefix=prefix)
+
+if __name__ == '__main__':
+    main()

+ 126 - 0
jupyter-mysql-kernel/kernel.py

@@ -0,0 +1,126 @@
+"""
+	jupyter-mysql-kernel
+	author:rabin
+"""
+from ipykernel.kernelbase import Kernel
+from .parser import MysqlParser
+import os.path
+import sys
+import re
+import pymysql
+
+__version__ = '0.0.1'
+
+version_pat = re.compile(r'version (\d+(\.\d+)+)')
+
+class MysqlKernel(Kernel):
+	implementation = 'jupyter-mysql-kernel'
+	implementation_version = __version__
+
+	@property
+	def language_version(self):
+		m = version_pat.search(self.banner)
+		return m.group(1)
+
+	_banner = None
+
+	@property
+	def banner(self):
+		if self._banner is None:
+			self._banner = 'mysql kernel'
+		return self._banner
+
+	language_info = {'name': 'mysql',
+					 'mimetype': 'text/x-sh',
+					 'file_extension': '.sql'}
+
+	mysql_setting_file = os.path.join(os.path.expanduser('~'), '.local/config/mysql_config.json')
+	mysql_config = {
+		'user'	  : 'root'
+		,'host'	  : '192.168.15.10'
+		,'port'	  : '3309'
+		,'charset'   : 'utf8'
+		,'password'  : '123456'
+	}
+
+	def __init__(self, **kwargs):
+		Kernel.__init__(self, **kwargs)
+		if os.path.exists(self.mysql_setting_file):
+			with open(self.mysql_setting_file,"r") as f:
+				self.mysql_config.update(json.load(f))
+		self.parser = MysqlParser()
+		self.connect()
+
+	def connect(self):
+		if self.parser.pandas():
+			cursorclass = pymysql.cursors.DictCursor
+		else:
+			cursorclass = pymysql.cursors.Cursor
+		try:
+			self.connect = pymysql.connect(host=self.mysql_config['host'], port=int(self.mysql_config['port']), user=self.mysql_config['user'], charset=self.mysql_config['charset'], passwd=self.mysql_config['password'], cursorclass=cursorclass)
+			self.cursor = self.connect.cursor()
+		except Exception:
+			self.connect = False
+
+	def execute(self, sql):
+		if self.connect:
+			self.cursor.execute(sql)
+
+	def fetchall(self):
+		if self.connect:
+			if self.parser.pandas():
+				return self.cursor.fetchall()
+			else:
+				return self.cursor
+		return False
+
+	def commit(self):
+		if self.connect:
+			self.connect.commit()
+
+	def output(self, output):
+		if not self.silent:
+			if type(output) != str:
+				output = self.parser.format(output)
+			display_content = {
+				'source': 'kernel',
+				'data': {
+					'text/html': output
+				}, 'metadata': {}
+			}
+			self.send_response(self.iopub_socket, 'display_data', display_content)
+
+	def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False):
+		self.silent = silent
+		if not code.strip():
+			return self.ok()
+		if not self.connect:
+			return self.err('Unable to connect to Mysql server. Check that the server is running.')
+
+		sql = code.rstrip()
+		output = ''
+		try:
+			for v in sql.split("\n"):
+				v = v.rstrip()
+				if len(v) > 0:
+					if v[0] == "#":
+						continue
+					self.execute(v)
+					if 'select' in v or 'show' in v:
+						output = self.fetchall()
+					else:
+						self.commit()
+						output = 'yes'
+			self.output(output)
+			return self.ok()
+		except Exception as msg:
+			self.output(format(msg))
+			return self.err('Error executing code ' + sql)
+
+	def ok(self):
+		return {'status': 'ok', 'execution_count': self.execution_count,
+                    'payload': [], 'user_expressions': {}}
+
+	def err(self, msg):
+		return {'status': 'error', 'error' : msg, 'traceback': [msg], 'execution_count': self.execution_count,
+                    'payload': [], 'user_expressions': {}}

+ 25 - 0
jupyter-mysql-kernel/parser.py

@@ -0,0 +1,25 @@
+"""
+	jupyter-mysql-kernel
+	author:rabin
+"""
+
+class MysqlParser():
+	def __init__(self, **kwargs):
+		try:
+			self.load = __import__('pandas')
+			self.type = 'pandas'
+		except ImportError as msg:
+			self.load = __import__('prettytable')
+			self.type = 'prettytable'
+
+	def pandas(self):
+		if self.type == 'pandas':
+			return True
+		return False
+
+	def format(self, content):
+		if self.type == 'pandas':
+			content = self.load.DataFrame(content).to_html()
+		else:
+			content = self.load.from_db_cursor(content).get_html_string()
+		return content

+ 57 - 0
setup.py

@@ -0,0 +1,57 @@
+from distutils.core import setup
+from distutils.command.install import install
+from distutils import log
+
+import json
+import os
+import sys
+
+kernel_json = { 'argv': ['python', '-m' ,'jupyter-mysql-kernel',
+						 '-f', '{connection_file}'],
+				'display_name': 'Mysql',
+				'language': 'mysql',
+				}
+
+# this code from bash_kernel made by Thomas Kluyver
+# (https://github.com/takluyver/bash_kernel)
+class install_with_kernelspec(install):
+	def run(self):
+		# Regular installation
+		install.run(self)
+
+		# Now write the kernelspec
+		from IPython.kernel.kernelspec import install_kernel_spec
+		from IPython.utils.tempdir import TemporaryDirectory
+		with TemporaryDirectory() as td:
+			os.chmod(td, 0o755) # Starts off as 700, not user readable
+			with open(os.path.join(td, 'kernel.json'), 'w') as f:
+				json.dump(kernel_json, f, sort_keys=True)
+			# TODO: Copy resources once they're specified
+
+			log.info('Installing IPython kernel spec')
+			install_kernel_spec(td, 'jupyter-mysql-kernel', user=self.user, replace=True)
+
+with open('README.md','r') as f:
+	readme = f.read()
+
+svem_flag = '--single-version-externally-managed'
+if svem_flag in sys.argv:
+	sys.argv.remove(svem_flag)
+
+setup(name='jupyter-mysql-kernel',
+	  version='0.0.1',
+	  description='A mysql kernel for Jupyter',
+	  long_description=readme,
+	  author='rabin',
+	  author_email='2934170@gmail.com',
+	  url='https://github.com/shemic/jupyter-mysql-kernel',
+	  packages=['jupyter-mysql-kernel'],
+	  cmdclass={'install': install_with_kernelspec},
+	  install_requires=['prettytable>=0.7.0'],
+	  classifiers = [
+		  'Framework :: IPython',
+		  'License :: OSI Approved :: BSD License',
+		  'Programming Language :: Python :: 3',
+		  'Topic :: System :: Shells',
+	  ]
+)