fundgz 命令行工具
一朋友在上班期間看手機(jī)基金信息扣泊,但上班期間頻繁看手機(jī)著實(shí)不太好近范,于是就想到寫一個(gè)能在命令行查看 fund 估值的命令行工具延蟹,通過輸入 fund 編號(hào)和名稱评矩,就能查詢到當(dāng)前時(shí)間的估值。 網(wǎng)絡(luò)上有很多這樣的摸魚插件阱飘,甚至在 vscode 里的插件比比皆是斥杜。 本著練手的態(tài)度,自己也寫了一個(gè)簡單的工具沥匈,就當(dāng)做學(xué)習(xí)新的庫了蔗喂。
使用預(yù)覽
安裝工具:
pipinstall fundgz
使用:
> fundgzUsage: fundgz [OPTIONS] COMMAND [ARGS]...Options:? --help? Showthismessageandexit.Commands:? adddeleterun
命令行輸入 fundgz 命令,可以查看這個(gè)命令的簡介高帖,可以看到提供了三個(gè)子命令:
> fundgz add正在添加 fund 文檔缰儿,ctrl+d 退出請(qǐng)輸入fund 編號(hào): 078943請(qǐng)輸入fund 名稱:test
輸入 fundgz add 命令,終端會(huì)提示輸入 fund 編號(hào)和名稱散址,輸入完成后乖阵,可以按 ctrl+d 退出。
fundgz delete 命令刪除錄入文檔的編號(hào)
fundgz run 命令就是根據(jù)之前存入的文檔執(zhí)行查詢了:
在終端會(huì)展示結(jié)果表格
開發(fā)思路
在終端錄入 fund code 并保存至臨時(shí)文件中
查詢臨時(shí)文件爪飘,提取其中的 fund code 列表
通過 code 列表义起,批量查詢 fund 當(dāng)日的估值信息
在終端列表展示
技術(shù)棧
python3.7 版本
數(shù)據(jù)抓取 - asyncio + aiohttp
命令行工具 - click + inquirer
終端展示 - rich
打包發(fā)布 - setuptools
click + inquirer 終端工具
使用 click.group() 創(chuàng)建命令組,實(shí)現(xiàn) add, delete 和 run 命令
@click.group()def fc():? ? pass@fc.command()def run():? ? pass@fc.command()def add():? ? pass@fc.command()def delete():? ? pass? ? fc()
@fc.command() 是為了替代 fc.add_command(run) 师崎,這樣寫更加優(yōu)雅
@click.command()defrun():passfc.add_command(run)
inquirer 庫是交互式工具默终,提供了很多便利的操作,這次使用的是 list 選擇犁罩。
執(zhí)行 fundgz delete 選擇要?jiǎng)h除的 code:
del_list=[inquirer.List('del',message="請(qǐng)選擇要?jiǎng)h除的 fund:",choices=codes)]del_answers=inquirer.prompt(del_list)
asyncio + aiohttp 批量數(shù)據(jù)查詢
讀取臨時(shí)文件后锥惋,提取出正在需要的 code 列表逾雄,通過這個(gè)列表批量查詢數(shù)據(jù)
asyncwithaiohttp.ClientSession()assession:? ? tasks = [asyncio.create_task(query_data(session, code))forcodeincodes]data= await asyncio.gather(*tasks)? ? print(data)
如果沒有查詢到數(shù)據(jù),則需要做好異常處理,則請(qǐng)求非 200 的則直接返回 None:
asyncdefquery_data(session, fund_code):"""
? ? :param fund_code:
? ? :return:
? ? """url = BASE_URL.format(fund_code)asyncwithsession.get(url=url)asresponse:ifresponse.status ==200:? ? ? ? ? ? bytes_data =awaitresponse.read()# 查看編碼類型ret = chardet.detect(bytes_data)# bytes 轉(zhuǎn)換成 strjsonp_data = str(bytes_data, ret['encoding'])# 判斷是否有數(shù)據(jù)data = re.match('.*?({.*}).*', jsonp_data, re.S).group(1)returnjson.loads(data)else:returnNone
如此溶弟,批量返回的數(shù)據(jù)中就會(huì)有 None,所以要 filter
data= filter(lambda fund: fund, data)
setuptools 打包
命令行工具已經(jīng)可以了锨侯,使用
pythonfundgz/main.py run
但是期望的是
fundgzrun
所以,就要將這個(gè)工具發(fā)布到服務(wù)上勺美。
首先在 https://pypi.org/ 上注冊(cè)一個(gè)賬號(hào),認(rèn)證郵箱等
其次碑韵,安裝 setuptools赡茸,更新至最新版:
python -m pipinstall--upgrade pip setuptools wheel
具體可以查看官網(wǎng)?
https://pypi.org/project/setuptools/
接下來就是打包的事兒了。
在項(xiàng)目根目錄下新建兩個(gè)文件 setup.py 和 setup.cfg
此時(shí)項(xiàng)目的結(jié)構(gòu)是
├──README.md├──fund-code.txt├──fundgz│? ├── __init__.py│? └──main.py├──setup.cfg└──setup.py
在 setup.py 文件內(nèi)祝闻,填寫打包的必要信息:
#!usr/bin/env python# -*- coding:utf-8 _*-fromsetuptoolsimportsetup, find_packagesVERSION ='0.1.7'setup(? ? name='fundgz',? ? version=VERSION,? ? description='fund search',? ? long_description='fund search',? ? keywords='fund asynico click rich inquirer',? ? author='caoshiping',? ? author_email='soraping@163.com',? ? url='https://github.com/soraping/fc',? ? license='MIT',? ? packages=find_packages(exclude=["*.txt"]),? ? include_package_data=True,? ? zip_safe=True,? ? install_requires=['aiohttp','inquirer','click','rich'],? ? python_requires='>=3.7',? ? entry_points={'console_scripts': ['fundgz = fundgz.main:main']? ? })
關(guān)鍵字段詳解:
name
上傳包的名稱
version
開發(fā)庫版本
packages
打包的內(nèi)容目錄占卧,使用 find_packages 方法,使用參數(shù) exclude 屏蔽一些文件
install_requires
所依賴的庫列表
entry_points
自定義命令联喘,不用 python xxxx.py 這樣執(zhí)行的华蜒,就要配置這個(gè)字段。這個(gè)字段不僅僅這個(gè)功能豁遭,當(dāng)前包通過 setuptools 注冊(cè)的一個(gè)外部可以直接調(diào)用的接口叭喜。
entry_points={'console_scripts': ['fundgz = fundgz.main:main']? ? }
在終端輸入:
$fundgz --helpusage: fundgz...
console_scripts 是自定義命令行列表
fundgz = fundgz.main:main,fundgz 是命令名稱堤框,等號(hào)右邊的是主方法路徑域滥,其中 fundgz.main 包根目錄下執(zhí)行文件的路徑,最后是執(zhí)行文件的方法名
setup.py 文件配置完成后就可以執(zhí)行打包操作了
在終端執(zhí)行命令:
# 使用sdist構(gòu)建源碼分發(fā)包pythonsetup.py sdist bdist_wheel
這里是固定的命令蜈抓,且在 setup.py 文件相同的目錄下執(zhí)行启绰,當(dāng)這個(gè)命令運(yùn)行結(jié)束后,確保在生成的 dist/ 文件夾下存在相應(yīng)的 .whl 文件和 .tar.gz 文件沟使。其中 .tar.gz 文件是我們 的python package 的源文件文檔委可。
而 .whl 是一個(gè)軟件分發(fā)包 (build distribution) 。新版本的 pip 將會(huì)首先嘗試安裝軟件分發(fā)包腊嗡,但在失敗情況下會(huì)接著嘗試采用源文件包安裝着倾。
執(zhí)行打包后,打開 dist 文件夾燕少,可以發(fā)現(xiàn)有 setup.py 配置的 name 和 version 拼接的包文件卡者,這些就是待上傳的包
上傳包
需要安裝上傳工具 twine
pipinstall --user --upgrade twine# 上傳twineupload dist/*
上傳的時(shí)候,會(huì)提示輸入 pypi 賬號(hào)密碼客们。
也可以指定版本號(hào)上傳
twineupload dist/fundgz-0.1.7*
到此崇决,一個(gè)包就算上傳成功了,可以下載下來試下
> pip install fundgz --upgrade>fundgz --help