├── .gitattributes
├── .gitignore
├── README.md
├── __init__.py
├── ngrok服务器搭建.docx
├── rqdata
├── __init__.py
├── mongo
│ ├── __init__.py
│ ├── client_template.py
│ ├── libs.py
│ └── mongo_server.py
└── rpc
│ ├── __init__.py
│ ├── client.py
│ └── server.py
├── scripts
├── __init__.py
├── future1m.py
├── passwd.py
├── rice_auto.py
├── rq.py
└── stock1m.py
├── setup.py
└── tests
├── __init__.py
└── test_server.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | .idea
10 |
11 | passwd.py
12 |
13 | # Distribution / packaging
14 | .Python
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib/
22 | lib64/
23 | parts/
24 | sdist/
25 | var/
26 | wheels/
27 | *.egg-info/
28 | .installed.cfg
29 | *.egg
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | .hypothesis/
51 |
52 | # Translations
53 | *.mo
54 | *.pot
55 |
56 | # Django stuff:
57 | *.log
58 | local_settings.py
59 |
60 | # Flask stuff:
61 | instance/
62 | .webassets-cache
63 |
64 | # Scrapy stuff:
65 | .scrapy
66 |
67 | # Sphinx documentation
68 | docs/_build/
69 |
70 | # PyBuilder
71 | target/
72 |
73 | # Jupyter Notebook
74 | .ipynb_checkpoints
75 |
76 | # pyenv
77 | .python-version
78 |
79 | # celery beat schedule file
80 | celerybeat-schedule
81 |
82 | # SageMath parsed files
83 | *.sage.py
84 |
85 | # Environments
86 | .env
87 | .venv
88 | env/
89 | venv/
90 | ENV/
91 |
92 | # Spyder project settings
93 | .spyderproject
94 | .spyproject
95 |
96 | # Rope project settings
97 | .ropeproject
98 |
99 | # mkdocs documentation
100 | /site
101 |
102 | # mypy
103 | .mypy_cache/
104 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | rq-data
2 | ==============
3 |
4 | 获取ricequant中数据, 其中期货数据默认为vnpy格式。
5 |
6 |
7 |
8 |
9 |
10 | 准备工作:
11 | 1. 公网IP的网络(若没有可以使用ngrok工具,详细使用方法自行google或参照本目录下的word教程)
12 | 2. 安装配置mongodb数据库(或根据自己需求,修改rpc的回调函数,存其它数据库,或者csv)
13 |
14 | 使用步骤:
15 | 1. 在拥有公网ip的电脑上运行rpc服务器端 `rqdata/mongo/mongo_server.py`,并配置其中的mongodb以及rpc服务器端口
16 | 2. 将`rqdata/rpc/client.py` 上传到 ricequant研究中的notebook中,放到文件夹rpc下,重命名为rpc.py
17 | 3. 在研究中新建notebook名为:test.ipynb, 并将`rqdata/scripts/`中`[future1m.py, stock1m.py, rq.py]`中的某个代码copy进去,修改其中的rpc客户端地址和端口,或者参照自行编写其它数据获取代码。(vnpy格式数据代码在future1m.py中)
18 |
19 |
20 | ##### 若手动下载直接运行第3步中代码,每日自动更新继续下述配置
21 |
22 | 准备工作:
23 | 1. 配置selenium环境(下载chromewebdriver,并将其路径添加到环境变量PATH中,自行翻墙下载或见群文件)
24 |
25 |
26 | 使用步骤:
27 | 1. 在`rqdata/scripts/passwd.py中配置ricequant的用户名密码
28 | 2. 将`driver.get("https://www.ricequant.com/research/user/user_xxxxx/notebooks/test.ipynb")`中的
29 | url路径改为步骤3中test.ipynb的路径。
30 | 3. 运行`rqdata/scripts/rice_auto.py`
31 |
32 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/__init__.py
--------------------------------------------------------------------------------
/ngrok服务器搭建.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/ngrok服务器搭建.docx
--------------------------------------------------------------------------------
/rqdata/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/rqdata/__init__.py
--------------------------------------------------------------------------------
/rqdata/mongo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/rqdata/mongo/__init__.py
--------------------------------------------------------------------------------
/rqdata/mongo/client_template.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from rqdata.rpc.client import RpcClient
3 |
4 | if __name__ == '__main__':
5 | host = 'localhost'
6 | port = 1111
7 |
8 | client = RpcClient(host, port)
9 | date = client.latest_date("CF0000", type='future')
10 | date = client.latest_date("IC0000", type='future')
11 | print(date)
12 |
--------------------------------------------------------------------------------
/rqdata/mongo/libs.py:
--------------------------------------------------------------------------------
1 | from pymongo import MongoClient
2 | import pymongo
3 | import re
4 |
5 | '''
6 | - `type`: CS for common stock, future for future
7 |
8 | - `code`:
9 | '''
10 |
11 |
12 | class MongoHelper(object):
13 | host = "localhost"
14 | port = 27017
15 |
16 | stock_min_db = "A_stock_min"
17 | stock_min_collection = "A_stock_min"
18 |
19 | def __init__(self, host="localhost", port=27017):
20 | self.host = host
21 | self.port = port
22 |
23 | self.client = MongoClient(self.host, self.port)
24 | self.stock_db = self.client[self.stock_min_db]
25 |
26 | self.future_db = self.client['VnTrader_1Min_Db']
27 |
28 | def latest_date(self, code, type="CS"):
29 | if type == "CS":
30 | cursor = self.stock_db[code].find().sort(
31 | [("dt", pymongo.DESCENDING)]).limit(1)
32 | try:
33 | date = cursor.next()['dt']
34 | except Exception as e:
35 | date = None
36 | return date
37 | elif type == "future":
38 | collection = self.future_db[code]
39 | cursor = collection.find({}, {"date": 1, "_id": 0}).sort([("datetime", pymongo.DESCENDING)]).limit(1)
40 | try:
41 | date = cursor.next()['date']
42 | except Exception as e:
43 | date = None
44 | return date
45 |
46 | def get_order_book_id(self, code):
47 | if code[-2:] == "SH":
48 | return code[:-2] + "XSHG"
49 | else:
50 | return code[:-2] + "XSHE"
51 |
52 | def get_stock_code(self, code):
53 | if code[-4:] == "XSHG":
54 | return code[:-4] + "SH"
55 | else:
56 | return code[:-4] + "SZ"
57 |
58 | def insert(self, code, data, type="CS"):
59 | if type == "CS":
60 | try:
61 | self.future_db[code].create_index([('datetime',pymongo.ASCENDING)],unique=True)
62 | except Exception as e:
63 | pass
64 | self.stock_db[code].insert(data)
65 | # for d in data:
66 | # self.stock_db[code].update({'datetime':d['datetime']},d,upsert=True)
67 | elif type == "future":
68 | try:
69 | self.future_db[code].create_index([('datetime',pymongo.ASCENDING)],unique=True)
70 | except Exception as e:
71 | pass
72 | self.future_db[code].insert(data)
73 | # for d in data:
74 | # self.future_db[code].update({'datetime':d['datetime']},d,upsert=True)
75 |
--------------------------------------------------------------------------------
/rqdata/mongo/mongo_server.py:
--------------------------------------------------------------------------------
1 | from six import PY2
2 |
3 | if PY2:
4 | import SocketServer
5 | else:
6 | import socketserver as SocketServer
7 | from rqdata.mongo.libs import *
8 | from rqdata.rpc.server import RpcHandler
9 |
10 |
11 | def run_server():
12 | mongo_helper = MongoHelper("127.0.0.1", 27017)
13 | host = '0.0.0.0'
14 | port = 1111
15 | RpcHandler.register(mongo_helper.latest_date)
16 | RpcHandler.register(mongo_helper.insert)
17 | server = SocketServer.TCPServer((host, port), RpcHandler)
18 | server.serve_forever()
19 |
--------------------------------------------------------------------------------
/rqdata/rpc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/rqdata/rpc/__init__.py
--------------------------------------------------------------------------------
/rqdata/rpc/client.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import zlib
4 | import socket
5 | import struct
6 | import threading
7 | import pickle
8 |
9 |
10 | def send_msg(sock, msg):
11 | # Prefix each message with a 4-byte length (network byte order)
12 | msg = zlib.compress(pickle.dumps(msg, protocol=2), 3)
13 | length = len(msg)
14 | msg = struct.pack('>I', length) + msg
15 | sock.sendall(msg)
16 |
17 |
18 | def recv_msg(sock):
19 | # Read message length and unpack it into an integer
20 | raw_msglen = sock.recv(4)
21 | if not raw_msglen:
22 | return None
23 | msglen = struct.unpack('>I', raw_msglen)[0]
24 | # Read the message data
25 | return recvall(sock, msglen)
26 |
27 |
28 | def recvall(sock, n):
29 | # Helper function to recv n bytes or return None if EOF is hit
30 | total_data = []
31 | data = b''
32 | byte_recved = 0
33 | while byte_recved < n:
34 | packet = sock.recv(n - byte_recved)
35 | if not packet:
36 | return None
37 | total_data.append(packet)
38 | byte_recved = byte_recved + len(packet)
39 | data = b''.join(total_data)
40 | return pickle.loads(zlib.decompress(data))
41 |
42 |
43 | class RpcClient(object):
44 | def __init__(self, address, port):
45 | self.address = address
46 | self.port = port
47 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
48 | errno = self.sock.connect_ex((address, port))
49 | if errno != 0:
50 | print("connectting to server failed")
51 |
52 | def __getattr__(self, name):
53 | """实现远程调用功能"""
54 |
55 | # 执行远程调用任务
56 | def dorpc(*args, **kwargs):
57 | # 生成请求
58 | req = [name, args, kwargs]
59 |
60 | send_msg(self.sock, req)
61 | repb = recv_msg(self.sock)
62 | return repb
63 |
64 | return dorpc
65 |
--------------------------------------------------------------------------------
/rqdata/rpc/server.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from rqdata.rpc.client import *
3 |
4 | from six import PY2
5 |
6 | if PY2:
7 | import SocketServer
8 | else:
9 | import socketserver as SocketServer
10 |
11 |
12 | class RpcHandler(SocketServer.StreamRequestHandler):
13 | __functions = {}
14 |
15 | def handle(self):
16 | while self.request:
17 | data = recv_msg(self.request)
18 | if not data:
19 | break
20 | name, args, kwargs = data
21 | func = RpcHandler.__functions[name]
22 | rt = func(*args, **kwargs)
23 | send_msg(self.request, rt)
24 |
25 | @staticmethod
26 | def register(func):
27 | RpcHandler.__functions[func.__name__] = func
28 |
29 |
30 | def hello(a):
31 | return 2 * a
32 |
33 |
34 | if __name__ == '__main__':
35 | host = 'localhost'
36 | port = 1111
37 | RpcHandler.register(hello)
38 | server = SocketServer.TCPServer((host, port), RpcHandler)
39 | server.serve_forever()
40 |
--------------------------------------------------------------------------------
/scripts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/scripts/__init__.py
--------------------------------------------------------------------------------
/scripts/future1m.py:
--------------------------------------------------------------------------------
1 | import re
2 | import socket
3 | import zlib
4 | import struct
5 | from pymongo import MongoClient
6 | import pymongo
7 | import datetime
8 | from rpc.rpc import RpcClient
9 |
10 | freq_int = {
11 | '1m': 1,
12 | '5m': 2,
13 | '10m': 3,
14 | '15m': 4,
15 | '30m': 5,
16 | '60m': 6,
17 | '1d': 7
18 | }
19 |
20 |
21 | ###公司mysql数据库格式
22 | def get_future_price1(code, start_date, end_date, frequency):
23 | df = get_price(code.upper(), start_date=start_date, end_date=end_date, frequency=frequency)
24 | df['dateInt'] = [int(i.strftime("%Y%m%d")) for i in df.index]
25 | df['timeInt'] = [int(i.strftime("%H%M%S")) for i in df.index]
26 | df['realDate'] = range(df.shape[0])
27 | df['vol'] = df['volume']
28 | df['openInt'] = df['open_interest']
29 | df['contract'] = re.match('[a-zA-Z]+', code).group()
30 | df['cycle'] = freq_int[frequency]
31 | del df['total_turnover']
32 | del df['volume']
33 | del df['trading_date']
34 | del df['limit_up']
35 | del df['limit_down']
36 | del df['basis_spread']
37 | del df['open_interest']
38 | return df
39 |
40 |
41 | ###vnpy回测mongodb格式
42 | def get_future_price2(code, start_date, end_date, frequency):
43 | contract = code + '0000'
44 | df = get_price(code.upper() + '88', start_date=start_date, end_date=end_date, frequency=frequency,
45 | adjust_type='post')
46 | df['vtSymbol'] = contract
47 | df['symbol'] = contract
48 | df['date'] = [int(i.strftime("%Y%m%d")) for i in df.index]
49 | df['time'] = [int(i.strftime("%H%M%S")) for i in df.index]
50 | df['datetime'] = df.index
51 | df['openInterest'] = df.open_interest
52 |
53 | del df['total_turnover']
54 | del df['trading_date']
55 | del df['limit_up']
56 | del df['limit_down']
57 | del df['basis_spread']
58 | del df['open_interest']
59 | return df
60 |
61 |
62 | ###插入到vnpy回测数据库中
63 | def insert_mongo2(client, code, frequency):
64 | start_date = client.latest_date(code + '0000', type='future')
65 | if not start_date:
66 | start_date = '20100104'
67 | print(code, "no begin_date, set default: 20100104")
68 |
69 | else:
70 | print("\r{}, start date: {}".format(code, start_date), end='')
71 | start_date = datetime.datetime.strptime(str(start_date), "%Y%m%d") + datetime.timedelta(1)
72 |
73 | end_date = datetime.datetime.now().date()
74 | if start_date.date() > end_date:
75 | return
76 | df = get_future_price2(code, start_date, end_date, frequency)
77 | if df.empty:
78 | return
79 | client.insert(code + '0000', df.to_dict('record'), type="future")
80 |
81 |
82 | codes = ["IC", "IF", "IH", "T", "TF", "CF", "FG", "MA", "OI", "RM", "SR",
83 | "TA", "ZC", "a", "c", "i", "j", "jd", "jm", "l", "m", "p", "pp",
84 | "v", "y", "ag", "al", "au", "bu", "cu", "hc", "ni", "pb", "rb",
85 | "ru", "sn", "zn"]
86 |
87 | code = 'rb'
88 | frequency = '1m'
89 | host = "carniejq.cn"
90 | port = 31245
91 | client = RpcClient(host, port)
92 | # insert_mongo2(client,code,frequency)
93 | for code in codes:
94 | insert_mongo2(client, code, frequency)
95 | print("\rfinished, stoping", end='')
96 | client.stop_all()
--------------------------------------------------------------------------------
/scripts/passwd.py:
--------------------------------------------------------------------------------
1 | user_name = ''
2 |
3 | passwd = ''
4 |
--------------------------------------------------------------------------------
/scripts/rice_auto.py:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | from selenium import webdriver
3 | from selenium.webdriver.common.by import By
4 | from selenium.webdriver.support.ui import WebDriverWait
5 | from selenium.webdriver.support import expected_conditions as EC
6 | import time
7 | from passwd import *
8 | from rqdata.mongo.mongo_server import run_server
9 | from rqdata.rpc.server import RpcHandler
10 | import threading
11 | import subprocess
12 | import sys
13 |
14 |
15 | def run_auto():
16 | driver = webdriver.Chrome()
17 | driver.get("https://www.ricequant.com/login")
18 | time.sleep(2)
19 | try:
20 | element = WebDriverWait(driver, 10).until(
21 | EC.presence_of_element_located((By.XPATH, '//*[@id="page-register"]/main/div[2]/form[4]/div[2]/input'))
22 | )
23 | finally:
24 | if user_name == '':
25 | raise Exception('place configure user name in scripts/passwd.py')
26 | element.send_keys(user_name)
27 | element = driver.find_element_by_xpath('//*[@id="page-register"]/main/div[2]/form[4]/div[4]/input')
28 | if passwd == '':
29 | raise Exception('please configure passwd in scritps/passwd.py')
30 | element.send_keys(passwd)
31 | element = driver.find_element_by_xpath('//div/input[@value="登录"]')
32 | element.click()
33 | try:
34 | element = WebDriverWait(driver, 10).until(
35 | lambda _: u"策略列表" in driver.page_source
36 | )
37 | finally:
38 | pass
39 | driver.get("https://www.ricequant.com/research/user/user_310960/notebooks/future.ipynb")
40 | driver.get("https://www.ricequant.com/research/user/user_310960/notebooks/future.ipynb")
41 | time.sleep(2)
42 | element = driver.find_element_by_xpath('//button[@title="run cell, select below"]')
43 | element.click()
44 | while not stop:
45 | pass
46 | driver.close()
47 |
48 |
49 | stop = False
50 |
51 |
52 | def stop_all():
53 | global stop
54 | stop = True
55 |
56 |
57 | if __name__ == '__main__':
58 | RpcHandler.register(stop_all)
59 | t = threading.Thread(target=run_server, daemon=True)
60 | t.start()
61 | t1 = threading.Thread(target=run_auto, daemon=True)
62 | t1.start()
63 |
64 | p=subprocess.Popen(r'C:\Users\jayso\Desktop\ngrok4.exe -config C:\Users\jayso\Desktop\.ngrok start-all',cwd=r'C:\Users\jayso\Desktop', shell=True, stdout=subprocess.PIPE)
65 |
66 | while not stop:
67 | pass
68 |
69 | p.kill()
70 |
--------------------------------------------------------------------------------
/scripts/rq.py:
--------------------------------------------------------------------------------
1 | from rpc.rpc import RpcClient
2 | import datetime
3 | import logging
4 | import pandas as pd
5 | import click
6 | import time
7 |
8 | '''
9 | rice quant code to download minute bars data
10 |
11 | '''
12 |
13 |
14 | def get_stock_list():
15 | df_instruments = all_instruments(type="CS")
16 | stocks = list(df_instruments["order_book_id"])
17 | stocks = list(map(lambda x: str(x), stocks))
18 | return stocks
19 |
20 |
21 | def insert_one(client, code, default_start='20050104'):
22 | start_date = client.latest_date(code)
23 | start_date = start_date + datetime.timedelta(1) if start_date else default_start
24 | end_date = pd.to_datetime('today').strftime("%Y%m%d")
25 | df = get_price(code, start_date=start_date, end_date=end_date, adjust_type='none', frequency='1m')
26 | if not df.empty:
27 | df['dt'] = df.index
28 | client.insert(code, df.to_dict('record'))
29 |
30 |
31 | def test():
32 | host = 'www.carniejq.cn'
33 | port = 31245
34 | code = "000007.XSHE"
35 | client = RpcClient(host, port)
36 | with click.progressbar(get_stock_list(),
37 | label="Fetching minute bars:",
38 | item_show_func=lambda e: e if e is None else str(e),
39 | ) as bar:
40 | bar.is_hidden = False
41 | for code in bar:
42 | insert_one(client, code, default_start='20171111')
43 | client.stop_all()
44 |
45 |
46 | test()
47 |
--------------------------------------------------------------------------------
/scripts/stock1m.py:
--------------------------------------------------------------------------------
1 | from rpc.rpc import RpcClient
2 | import datetime
3 | import logging
4 | import pandas as pd
5 |
6 |
7 | def get_wind_code(order_book_id):
8 | stock_code = order_book_id[0:6]
9 | if order_book_id[9:] == "HG":
10 | return stock_code + ".SH"
11 | return stock_code + ".SZ"
12 |
13 |
14 | def get_stock_list():
15 | df_instruments = all_instruments(type="CS")
16 | stocks = list(df_instruments["order_book_id"])
17 | stocks = list(map(lambda x: str(x), stocks))
18 | return stocks
19 |
20 |
21 | def insert_stock(code, client):
22 | begin_date = client.latest_date(code, type='CS')
23 | if not begin_date:
24 | logging.info(code + " failed, begin_date returned None")
25 | return
26 | begin_date = datetime.datetime.strptime(str(begin_date), "%Y%m%d") + datetime.timedelta(1)
27 | end_date = datetime.datetime.now().date()
28 |
29 | df = get_price(code, start_date=begin_date, end_date=end_date, adjust_type="post",
30 | frequency="1d", skip_suspended=True)
31 | if df.empty:
32 | logging.info(code + "empty df")
33 | return
34 | df['time'] = [int(i.strftime("%H%M%S")) for i in df.index]
35 | df['date'] = [i.strftime("%Y%m%d") for i in df.index]
36 | df['amt'] = df['total_turnover']
37 | del df['total_turnover']
38 | group_data = []
39 | for name, sub_group in df.groupby('date'):
40 | dict_data = sub_group.to_dict('list')
41 | dict_data.update({'date': sub_group['date'].iloc[0]})
42 | dict_data.update({'order_book_id': code})
43 | dict_data.update({'wind_code': get_wind_code(code)})
44 | dict_data.update({'stock_code': code[:6]})
45 | group_data.append(dict_data)
46 | client.insert(group_data)
47 |
48 |
49 | def main():
50 | # insert_stock(code,client)
51 | logging.basicConfig(filename='stock_1m.log', level=logging.INFO)
52 | host = 'www.carniejq.cn'
53 | port = 1111
54 | code = "000007.XSHE"
55 | import time
56 |
57 | client = RpcClient(host, port)
58 | count = 0
59 | stock_list = get_stock_list()
60 | for stock in stock_list:
61 | insert_stock(stock, client)
62 | if count % 50 == 0:
63 | print("\r %f percent complete" % (float(count) / len(stock_list) * 100), end="")
64 | count = count + 1
65 | print("\r finished")
66 | client.stop_all()
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from setuptools import setup, find_packages
4 |
5 | try:
6 | import pypandoc
7 |
8 | long_description = pypandoc.convert('README.md', 'rst')
9 | except (IOError, ImportError):
10 | long_description = ''
11 |
12 | setup(
13 | name='rq-data',
14 | version='0.01',
15 | description='rq data tools',
16 | long_description=long_description,
17 | author='Jie Wang',
18 | author_email='790930856@qq.com',
19 | url='https://github.com/JaysonAlbert/rq-data',
20 | packages=find_packages(include=['rq-data', 'rq-data.*']),
21 |
22 | install_requires=[
23 | 'selenium',
24 | 'pymongo'
25 | ]
26 | )
27 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JaysonAlbert/rq-data/782b979903e7d4c01e5a42f7eac8669c84c3b776/tests/__init__.py
--------------------------------------------------------------------------------
/tests/test_server.py:
--------------------------------------------------------------------------------
1 | from six import PY2
2 |
3 | if PY2:
4 | import SocketServer
5 | else:
6 | import socketserver as SocketServer
7 | from rqdata.rpc.server import RpcHandler
8 | import pickle
9 |
10 | host = 'localhost'
11 | port = 1111
12 | RpcHandler.register(print)
13 | server = SocketServer.TCPServer((host, port), RpcHandler)
14 | server.serve_forever()
--------------------------------------------------------------------------------