# 原子能力的代码怎么写
“原子能力”,可以是实现一个API接口的访问、一个大模型的调用、一个数据的校验等等。
需要用python来编写“原子能力”的代码,不是从头到尾去写一个python程序,而是按照业务逻辑写一段可以用的python函数,来实现智能体的“原子能力”。
在编写python的时候要注意,不能随意发挥,需要在一定的条条款款下来编码,原因是只能这样编写智能体才能调用起来你的原子能力。
## 基本要求
- 人:有基础的python编程能力
- python版本:基于3.10.*
- python依赖库,只能用智能体现有的依赖库,常用的都具备(requests、json这些基础的都有),特殊的库没法自行添加(可以尝试自行封装一个API服务,让原子能力调用)。
## 代码编写指导
先配置环境,创建一个python环境,并使用pip安装hirpafnwheel
```shell
pip install hirpafnwheel
```
再新建一个新的python文件,在里面写业务逻辑,并且单元测试没有问题后,再把代码并入到“原子能力”的代码中。
“原子能力”的代码有个固定结构,class和里面的exec函数不能修改,业务代码放到exec里面就可以了,需要用到的库直接在最外面import就行。
示例如下:
这是一个把智能体抽取的入参当出参的“原子能力”,通常用于测试智能体的参数抽取功能。
```py
# ===================这里的都不要动================
# 此部分为插件引擎环境的相关引用
import sys
sys.path.insert(0, ".")
from hirpa.biz.services.fn.fn_code import FnCode
from hirpa.biz.services.fn.fn_tool_base import FnToolBase
from hirpa.utils.result import gen_result
# ===================可以根据需求自定引用===================
# 可以根据自己的业务需求,自行引用相关组件
# 注意:当前环境局限,只有常用库可用,后期会加入自动拉去加载依赖库功能
import logging as logger # 日志库
import requests, json # 常用的http请求、json解析等
# ===================调用的函数=======================
# 类、函数、入参,均不要修改
class FnCodePlug(FnCode):
def exec(self, fnTool: FnToolBase, extend: dict = None) -> dict:
# fnTool,为插件的上下文信息
# entend,为扩展的信息,
# ==============此处可以根据需求编写代码==============
try:
in_args = fnTool.get_in_args() # 获取所有的入参
msg = {}
for _, a in in_args.items():
av = {}
av["field_type"] = "text"
av["cn_name"] = a.cn_name
av["value"] = a.value
msg[a.name] = av
if extend != None:
for k, v in extend.items():
msg[k] = {"field_type": "text", "cn_name": f"extend_{v}", "value": v}
# 返回结果,必须按照此格式返回
return gen_result(
status="9", # 参考[结果状态],9=成功
unique_no=fnTool.get_unique_no(), # 不动
msg=msg, # 返回给用户的内容,需要按照规范来,参考[返回的内容]章节
biz_name=fnTool.get_name(), # 不动
biz_cn_name=fnTool.get_cn_name(), # 不动
)
# 异常处理
except Exception as ex:
logger.exception(ex)
return gen_result(
status="0", # 参考[结果状态],0=异常
unique_no=fnTool.get_unique_no(),
biz_name=fnTool.get_name(),
biz_cn_name=fnTool.get_cn_name(),
msg=f"执行失败,【{ex}】",
)
```
### 结果状态
- "0" ,执行异常
- "1" , 提示用户输入,目的是抽取动态参数,或者入参不合规,重新抽取
- "3" , 提醒消息,自定义信息给用户展示
- "9" , 执行成功
### 返回的内容
结果状态=0时,执行异常
格式:字符串
内容:放入详细异常信息,格式于聊天页面商量
----
结果状态=1时,提示用户输入
格式:dict
内容:为要从用户那获取的参数,参数必须在原子能力的入参中,包含动态参数
示例:
```json
{
"出参1英文名":{
"human_prompt":"出参值"
},
"出参2英文名":{
"human_prompt":""
}
}
```
----
结果状态=3时,发提醒信息给用户
格式:字符串
内容:提醒的内容,格式跟聊天页面的开发要协商好
----
结果状态=9,执行成功
dict对象,要与“原子能力”的出入参匹配,不允许输出
示例:
```json
{
"出参1英文名":{
"value":"出参值"
},
"出参2英文名":{
"value":"出参值"
}
}
```
## 示例
一个查询当前天气的原子能力代码
```py
import sys
sys.path.insert(0, ".")
from hirpa.biz.agent.tools.fn_code import FnCode
from hirpa.biz.agent.tools.fn_tool_base import FnToolBase
from hirpa.llm.message import BaseMessage, SystemMessage, UserMessage
import hirpa.biz.agent.tools.fn_code_helper as fn_code_helper
import requests, json, traceback
import logging as logger
class FnCodePlug(FnCode):
async def exec(self, fnTool: FnToolBase, extend: dict = None) -> dict:
try:
in_args = fnTool.get_in_args()
logger.debug(f"查询城市:{in_args[list(in_args.keys())[0]].get_value()}")
response = requests.get(
f"https://free.wqwlkj.cn/wqwlapi/weather.php?city={in_args[list(in_args.keys())[0]].get_value()}",
)
resp_str = response.text
logger.debug(f"接口返回:{resp_str}")
messages: list[BaseMessage] = []
messages.append(
SystemMessage(
content="你是一个天气预报员,并帮我把一下内容整理为一份完成天气预报,通过markdown格式输出,必须包含markdown特有的格式、图标、表情、引用等,其中生活指数与建议用table展示,内容简要精确,总共不超过200个字。"
)
)
messages.append(
UserMessage(
content=f"{resp_str}",
example=True,
)
)
data = fnTool.chat(messages)
return fn_code_helper.return_success(
fnTool,
{
"result": {
"field_type": "text",
"cn_name": "查询结果",
"value": data,
}
},
)
except Exception as ex:
logger.exception(f"代码执行异常:{ex}")
return fn_code_helper.return_exception(fnTool, f"执行失败,系统内部错误")
```
Raw data
{
"_id": null,
"home_page": "http://airpa.asiainfo.com.cn",
"name": "hirpafnwheel",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": null,
"author": "AISware RPA Team",
"author_email": "airpa@asiainfo.com",
"download_url": "https://files.pythonhosted.org/packages/42/e3/c27807bd3adafd746595cfae52ee8c5eb8611cb6bebe39a2a914c4f9e78a/hirpafnwheel-0.1.1.tar.gz",
"platform": null,
"description": "# \u539f\u5b50\u80fd\u529b\u7684\u4ee3\u7801\u600e\u4e48\u5199\r\n\r\n\u201c\u539f\u5b50\u80fd\u529b\u201d\uff0c\u53ef\u4ee5\u662f\u5b9e\u73b0\u4e00\u4e2aAPI\u63a5\u53e3\u7684\u8bbf\u95ee\u3001\u4e00\u4e2a\u5927\u6a21\u578b\u7684\u8c03\u7528\u3001\u4e00\u4e2a\u6570\u636e\u7684\u6821\u9a8c\u7b49\u7b49\u3002\r\n\u9700\u8981\u7528python\u6765\u7f16\u5199\u201c\u539f\u5b50\u80fd\u529b\u201d\u7684\u4ee3\u7801\uff0c\u4e0d\u662f\u4ece\u5934\u5230\u5c3e\u53bb\u5199\u4e00\u4e2apython\u7a0b\u5e8f\uff0c\u800c\u662f\u6309\u7167\u4e1a\u52a1\u903b\u8f91\u5199\u4e00\u6bb5\u53ef\u4ee5\u7528\u7684python\u51fd\u6570\uff0c\u6765\u5b9e\u73b0\u667a\u80fd\u4f53\u7684\u201c\u539f\u5b50\u80fd\u529b\u201d\u3002\r\n\u5728\u7f16\u5199python\u7684\u65f6\u5019\u8981\u6ce8\u610f\uff0c\u4e0d\u80fd\u968f\u610f\u53d1\u6325\uff0c\u9700\u8981\u5728\u4e00\u5b9a\u7684\u6761\u6761\u6b3e\u6b3e\u4e0b\u6765\u7f16\u7801\uff0c\u539f\u56e0\u662f\u53ea\u80fd\u8fd9\u6837\u7f16\u5199\u667a\u80fd\u4f53\u624d\u80fd\u8c03\u7528\u8d77\u6765\u4f60\u7684\u539f\u5b50\u80fd\u529b\u3002\r\n\r\n## \u57fa\u672c\u8981\u6c42\r\n\r\n- \u4eba\uff1a\u6709\u57fa\u7840\u7684python\u7f16\u7a0b\u80fd\u529b\r\n- python\u7248\u672c\uff1a\u57fa\u4e8e3.10.*\r\n- python\u4f9d\u8d56\u5e93\uff0c\u53ea\u80fd\u7528\u667a\u80fd\u4f53\u73b0\u6709\u7684\u4f9d\u8d56\u5e93\uff0c\u5e38\u7528\u7684\u90fd\u5177\u5907\uff08requests\u3001json\u8fd9\u4e9b\u57fa\u7840\u7684\u90fd\u6709\uff09\uff0c\u7279\u6b8a\u7684\u5e93\u6ca1\u6cd5\u81ea\u884c\u6dfb\u52a0\uff08\u53ef\u4ee5\u5c1d\u8bd5\u81ea\u884c\u5c01\u88c5\u4e00\u4e2aAPI\u670d\u52a1\uff0c\u8ba9\u539f\u5b50\u80fd\u529b\u8c03\u7528\uff09\u3002\r\n\r\n## \u4ee3\u7801\u7f16\u5199\u6307\u5bfc\r\n\r\n\u5148\u914d\u7f6e\u73af\u5883\uff0c\u521b\u5efa\u4e00\u4e2apython\u73af\u5883\uff0c\u5e76\u4f7f\u7528pip\u5b89\u88c5hirpafnwheel\r\n\r\n```shell\r\npip install hirpafnwheel\r\n```\r\n\r\n\u518d\u65b0\u5efa\u4e00\u4e2a\u65b0\u7684python\u6587\u4ef6\uff0c\u5728\u91cc\u9762\u5199\u4e1a\u52a1\u903b\u8f91\uff0c\u5e76\u4e14\u5355\u5143\u6d4b\u8bd5\u6ca1\u6709\u95ee\u9898\u540e\uff0c\u518d\u628a\u4ee3\u7801\u5e76\u5165\u5230\u201c\u539f\u5b50\u80fd\u529b\u201d\u7684\u4ee3\u7801\u4e2d\u3002\r\n\r\n\u201c\u539f\u5b50\u80fd\u529b\u201d\u7684\u4ee3\u7801\u6709\u4e2a\u56fa\u5b9a\u7ed3\u6784\uff0cclass\u548c\u91cc\u9762\u7684exec\u51fd\u6570\u4e0d\u80fd\u4fee\u6539\uff0c\u4e1a\u52a1\u4ee3\u7801\u653e\u5230exec\u91cc\u9762\u5c31\u53ef\u4ee5\u4e86\uff0c\u9700\u8981\u7528\u5230\u7684\u5e93\u76f4\u63a5\u5728\u6700\u5916\u9762import\u5c31\u884c\u3002\r\n\r\n\u793a\u4f8b\u5982\u4e0b\uff1a\r\n\u8fd9\u662f\u4e00\u4e2a\u628a\u667a\u80fd\u4f53\u62bd\u53d6\u7684\u5165\u53c2\u5f53\u51fa\u53c2\u7684\u201c\u539f\u5b50\u80fd\u529b\u201d\uff0c\u901a\u5e38\u7528\u4e8e\u6d4b\u8bd5\u667a\u80fd\u4f53\u7684\u53c2\u6570\u62bd\u53d6\u529f\u80fd\u3002\r\n\r\n```py\r\n# ===================\u8fd9\u91cc\u7684\u90fd\u4e0d\u8981\u52a8================\r\n# \u6b64\u90e8\u5206\u4e3a\u63d2\u4ef6\u5f15\u64ce\u73af\u5883\u7684\u76f8\u5173\u5f15\u7528\r\n\r\nimport sys\r\nsys.path.insert(0, \".\")\r\n\r\nfrom hirpa.biz.services.fn.fn_code import FnCode\r\nfrom hirpa.biz.services.fn.fn_tool_base import FnToolBase\r\nfrom hirpa.utils.result import gen_result\r\n\r\n\r\n# ===================\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u81ea\u5b9a\u5f15\u7528===================\r\n# \u53ef\u4ee5\u6839\u636e\u81ea\u5df1\u7684\u4e1a\u52a1\u9700\u6c42\uff0c\u81ea\u884c\u5f15\u7528\u76f8\u5173\u7ec4\u4ef6\r\n# \u6ce8\u610f\uff1a\u5f53\u524d\u73af\u5883\u5c40\u9650\uff0c\u53ea\u6709\u5e38\u7528\u5e93\u53ef\u7528\uff0c\u540e\u671f\u4f1a\u52a0\u5165\u81ea\u52a8\u62c9\u53bb\u52a0\u8f7d\u4f9d\u8d56\u5e93\u529f\u80fd\r\n\r\nimport logging as logger # \u65e5\u5fd7\u5e93\r\nimport requests, json # \u5e38\u7528\u7684http\u8bf7\u6c42\u3001json\u89e3\u6790\u7b49\r\n\r\n# ===================\u8c03\u7528\u7684\u51fd\u6570=======================\r\n# \u7c7b\u3001\u51fd\u6570\u3001\u5165\u53c2\uff0c\u5747\u4e0d\u8981\u4fee\u6539\r\nclass FnCodePlug(FnCode):\r\n def exec(self, fnTool: FnToolBase, extend: dict = None) -> dict:\r\n # fnTool\uff0c\u4e3a\u63d2\u4ef6\u7684\u4e0a\u4e0b\u6587\u4fe1\u606f\r\n # entend\uff0c\u4e3a\u6269\u5c55\u7684\u4fe1\u606f\uff0c\r\n# ==============\u6b64\u5904\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u7f16\u5199\u4ee3\u7801==============\r\n \r\n try:\r\n in_args = fnTool.get_in_args() # \u83b7\u53d6\u6240\u6709\u7684\u5165\u53c2\r\n msg = {}\r\n for _, a in in_args.items():\r\n av = {}\r\n av[\"field_type\"] = \"text\"\r\n av[\"cn_name\"] = a.cn_name\r\n av[\"value\"] = a.value\r\n msg[a.name] = av\r\n\r\n if extend != None:\r\n for k, v in extend.items():\r\n msg[k] = {\"field_type\": \"text\", \"cn_name\": f\"extend_{v}\", \"value\": v}\r\n\r\n # \u8fd4\u56de\u7ed3\u679c\uff0c\u5fc5\u987b\u6309\u7167\u6b64\u683c\u5f0f\u8fd4\u56de\r\n return gen_result(\r\n status=\"9\", # \u53c2\u8003[\u7ed3\u679c\u72b6\u6001]\uff0c9=\u6210\u529f\r\n unique_no=fnTool.get_unique_no(), # \u4e0d\u52a8\r\n msg=msg, # \u8fd4\u56de\u7ed9\u7528\u6237\u7684\u5185\u5bb9\uff0c\u9700\u8981\u6309\u7167\u89c4\u8303\u6765\uff0c\u53c2\u8003[\u8fd4\u56de\u7684\u5185\u5bb9]\u7ae0\u8282\r\n biz_name=fnTool.get_name(), # \u4e0d\u52a8\r\n biz_cn_name=fnTool.get_cn_name(), # \u4e0d\u52a8\r\n )\r\n # \u5f02\u5e38\u5904\u7406\r\n except Exception as ex:\r\n logger.exception(ex)\r\n return gen_result(\r\n status=\"0\", # \u53c2\u8003[\u7ed3\u679c\u72b6\u6001]\uff0c0=\u5f02\u5e38\r\n unique_no=fnTool.get_unique_no(),\r\n biz_name=fnTool.get_name(),\r\n biz_cn_name=fnTool.get_cn_name(),\r\n msg=f\"\u6267\u884c\u5931\u8d25,\u3010{ex}\u3011\",\r\n )\r\n\r\n```\r\n\r\n### \u7ed3\u679c\u72b6\u6001\r\n\r\n- \"0\" \uff0c\u6267\u884c\u5f02\u5e38\r\n- \"1\" \uff0c \u63d0\u793a\u7528\u6237\u8f93\u5165\uff0c\u76ee\u7684\u662f\u62bd\u53d6\u52a8\u6001\u53c2\u6570\uff0c\u6216\u8005\u5165\u53c2\u4e0d\u5408\u89c4\uff0c\u91cd\u65b0\u62bd\u53d6\r\n- \"3\" \uff0c \u63d0\u9192\u6d88\u606f\uff0c\u81ea\u5b9a\u4e49\u4fe1\u606f\u7ed9\u7528\u6237\u5c55\u793a\r\n- \"9\" \uff0c \u6267\u884c\u6210\u529f\r\n\r\n### \u8fd4\u56de\u7684\u5185\u5bb9\r\n\r\n\u7ed3\u679c\u72b6\u6001=0\u65f6\uff0c\u6267\u884c\u5f02\u5e38\r\n\u683c\u5f0f\uff1a\u5b57\u7b26\u4e32\r\n\u5185\u5bb9\uff1a\u653e\u5165\u8be6\u7ec6\u5f02\u5e38\u4fe1\u606f\uff0c\u683c\u5f0f\u4e8e\u804a\u5929\u9875\u9762\u5546\u91cf\r\n\r\n----\r\n\r\n\u7ed3\u679c\u72b6\u6001=1\u65f6\uff0c\u63d0\u793a\u7528\u6237\u8f93\u5165\r\n\u683c\u5f0f\uff1adict\r\n\u5185\u5bb9\uff1a\u4e3a\u8981\u4ece\u7528\u6237\u90a3\u83b7\u53d6\u7684\u53c2\u6570\uff0c\u53c2\u6570\u5fc5\u987b\u5728\u539f\u5b50\u80fd\u529b\u7684\u5165\u53c2\u4e2d\uff0c\u5305\u542b\u52a8\u6001\u53c2\u6570\r\n\u793a\u4f8b\uff1a\r\n\r\n```json\r\n{\r\n \"\u51fa\u53c21\u82f1\u6587\u540d\":{\r\n \"human_prompt\":\"\u51fa\u53c2\u503c\"\r\n },\r\n \"\u51fa\u53c22\u82f1\u6587\u540d\":{\r\n \"human_prompt\":\"\"\r\n }\r\n}\r\n\r\n```\r\n\r\n----\r\n\r\n\u7ed3\u679c\u72b6\u6001=3\u65f6\uff0c\u53d1\u63d0\u9192\u4fe1\u606f\u7ed9\u7528\u6237\r\n\u683c\u5f0f\uff1a\u5b57\u7b26\u4e32\r\n\u5185\u5bb9\uff1a\u63d0\u9192\u7684\u5185\u5bb9\uff0c\u683c\u5f0f\u8ddf\u804a\u5929\u9875\u9762\u7684\u5f00\u53d1\u8981\u534f\u5546\u597d\r\n\r\n----\r\n\r\n\u7ed3\u679c\u72b6\u6001=9\uff0c\u6267\u884c\u6210\u529f\r\ndict\u5bf9\u8c61\uff0c\u8981\u4e0e\u201c\u539f\u5b50\u80fd\u529b\u201d\u7684\u51fa\u5165\u53c2\u5339\u914d\uff0c\u4e0d\u5141\u8bb8\u8f93\u51fa\r\n\u793a\u4f8b\uff1a\r\n\r\n```json\r\n{\r\n \"\u51fa\u53c21\u82f1\u6587\u540d\":{\r\n \"value\":\"\u51fa\u53c2\u503c\"\r\n },\r\n \"\u51fa\u53c22\u82f1\u6587\u540d\":{\r\n \"value\":\"\u51fa\u53c2\u503c\"\r\n }\r\n}\r\n```\r\n\r\n## \u793a\u4f8b\r\n\r\n\u4e00\u4e2a\u67e5\u8be2\u5f53\u524d\u5929\u6c14\u7684\u539f\u5b50\u80fd\u529b\u4ee3\u7801\r\n\r\n```py\r\nimport sys\r\n\r\nsys.path.insert(0, \".\")\r\n\r\nfrom hirpa.biz.agent.tools.fn_code import FnCode\r\nfrom hirpa.biz.agent.tools.fn_tool_base import FnToolBase\r\nfrom hirpa.llm.message import BaseMessage, SystemMessage, UserMessage\r\n\r\nimport hirpa.biz.agent.tools.fn_code_helper as fn_code_helper\r\nimport requests, json, traceback\r\nimport logging as logger\r\n\r\n\r\nclass FnCodePlug(FnCode):\r\n async def exec(self, fnTool: FnToolBase, extend: dict = None) -> dict:\r\n try:\r\n in_args = fnTool.get_in_args()\r\n logger.debug(f\"\u67e5\u8be2\u57ce\u5e02:{in_args[list(in_args.keys())[0]].get_value()}\")\r\n response = requests.get(\r\n f\"https://free.wqwlkj.cn/wqwlapi/weather.php?city={in_args[list(in_args.keys())[0]].get_value()}\",\r\n )\r\n\r\n resp_str = response.text\r\n logger.debug(f\"\u63a5\u53e3\u8fd4\u56de:{resp_str}\")\r\n\r\n messages: list[BaseMessage] = []\r\n messages.append(\r\n SystemMessage(\r\n content=\"\u4f60\u662f\u4e00\u4e2a\u5929\u6c14\u9884\u62a5\u5458\uff0c\u5e76\u5e2e\u6211\u628a\u4e00\u4e0b\u5185\u5bb9\u6574\u7406\u4e3a\u4e00\u4efd\u5b8c\u6210\u5929\u6c14\u9884\u62a5\uff0c\u901a\u8fc7markdown\u683c\u5f0f\u8f93\u51fa\uff0c\u5fc5\u987b\u5305\u542bmarkdown\u7279\u6709\u7684\u683c\u5f0f\u3001\u56fe\u6807\u3001\u8868\u60c5\u3001\u5f15\u7528\u7b49\uff0c\u5176\u4e2d\u751f\u6d3b\u6307\u6570\u4e0e\u5efa\u8bae\u7528table\u5c55\u793a\uff0c\u5185\u5bb9\u7b80\u8981\u7cbe\u786e\uff0c\u603b\u5171\u4e0d\u8d85\u8fc7200\u4e2a\u5b57\u3002\"\r\n )\r\n )\r\n messages.append(\r\n UserMessage(\r\n content=f\"{resp_str}\",\r\n example=True,\r\n )\r\n )\r\n data = fnTool.chat(messages)\r\n\r\n return fn_code_helper.return_success(\r\n fnTool,\r\n {\r\n \"result\": {\r\n \"field_type\": \"text\",\r\n \"cn_name\": \"\u67e5\u8be2\u7ed3\u679c\",\r\n \"value\": data,\r\n }\r\n },\r\n )\r\n\r\n except Exception as ex:\r\n logger.exception(f\"\u4ee3\u7801\u6267\u884c\u5f02\u5e38:{ex}\")\r\n return fn_code_helper.return_exception(fnTool, f\"\u6267\u884c\u5931\u8d25,\u7cfb\u7edf\u5185\u90e8\u9519\u8bef\")\r\n```\r\n",
"bugtrack_url": null,
"license": null,
"summary": "\u7528\u4e8e\u7f16\u5199hirpa\u4e2d\u539f\u5b50\u80fd\u91cc\u7684\u811a\u624b\u67b6\uff0c\u5bf9\u5e94Hirpa\u5f15\u64ce0.8.5\u4ee5\u4e0a\u7248\u672c",
"version": "0.1.1",
"project_urls": {
"Homepage": "http://airpa.asiainfo.com.cn"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "14b705dd42788d34c876b58630465412679c01b4a2ea84979cdc64f7578f832a",
"md5": "aa2623fa7ee929feed0226ef2ada73ac",
"sha256": "b94e5395bd4f263592e38e647bf6a5b220d50988b9409d5705aeddb75c165561"
},
"downloads": -1,
"filename": "hirpafnwheel-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "aa2623fa7ee929feed0226ef2ada73ac",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 15712,
"upload_time": "2024-11-05T09:57:35",
"upload_time_iso_8601": "2024-11-05T09:57:35.950303Z",
"url": "https://files.pythonhosted.org/packages/14/b7/05dd42788d34c876b58630465412679c01b4a2ea84979cdc64f7578f832a/hirpafnwheel-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "42e3c27807bd3adafd746595cfae52ee8c5eb8611cb6bebe39a2a914c4f9e78a",
"md5": "59ab90657f07342f7d26b215b17bcf12",
"sha256": "88f45a2a952c232c1462d241581b220e112c7bf0738b8817b99500fcd66ac60d"
},
"downloads": -1,
"filename": "hirpafnwheel-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "59ab90657f07342f7d26b215b17bcf12",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 15706,
"upload_time": "2024-11-05T09:57:37",
"upload_time_iso_8601": "2024-11-05T09:57:37.589482Z",
"url": "https://files.pythonhosted.org/packages/42/e3/c27807bd3adafd746595cfae52ee8c5eb8611cb6bebe39a2a914c4f9e78a/hirpafnwheel-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-05 09:57:37",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "hirpafnwheel"
}