我对Python打包相当陌生,我正在try 创建一个命令行工具,这样我就可以发送到客户端来与我在AWS中的服务交互.

我的目标是有一个命令行工具,将文件夹resources中的文件上传到S3,稍后将被其他服务使用.

这是我第一次使用设置工具来做这件事,但我似乎在某些时候迷失了方向.

我的项目 struct 类似于:

ProjectRoot
├── MANIFEST.in
├── Pipfile
├── Pipfile.lock
├── dist
│   ├── myscript-0.0.1.whl
│   └── myscript-0.0.1.tar.gz
├── pyproject.toml
├── resources
│   ├── artifacts
│   │   ├── code1.jar
│   │   ├── code2.jar
│   │   ├── api.keys
│   │   ├── package1.tar.gz
│   │   ├── install-linux.sh
│   │   └── confs.yaml
│   ├── recipe.template.yaml
└── src
    └── code
        ├── __init__.py
        └── myscript.py

我try 让setupTools使用以下内容将文件添加到.tar包中,其中包含以下内容:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "myscript"
version = "0.0.1"
dependencies = [
    'Click',
    'boto3',
    'botocore',
]

[project.scripts]
myscript = "code.main:run"

[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
where = ["src","resources"] 
include = ["code*"]
exclude = [] 

[tool.setuptools.package-data]
"resources.artifacts" = ["*"]
recipe = ["*.yaml"]

之后,我try 使用pip install dist/generated_file.whl安装轮子生成的文件,但在安装过程中找不到resources/文件夹.

附言:如果我同时需要WHL和TAR包,我也有点迷路了.

我try 使用相对路径来查找资源,但我发现它们没有安装在SitesPackages中.

我最近的一次try 是用from importlib_resources import files,但它似乎也找不到资源.

我找不到资源文件夹文件.

推荐答案

起点

使用给定的项目 struct

? <project root>/
├─? pyproject.toml
├─? src/
│ └─? code/
│   ├─? __init__.py
│   └─? myscript.py
├─? resources/
  └─? artifacts/
    └─? code1.jar

并通过指定

[tool.setuptools.packages.find]
where = ["src","resources"]
include = ["code*"]
exclude = []

[tool.setuptools.package-data]
"resources.artifacts" = ["*"]
recipe = ["*.yaml"]

你会得到一个轮子,里面有以下内容

? myscript-0.0.1-py3-none-any/
└─? code/
  ├─? __init__.py
  └─? myscript.py

这样做的原因是,唯一找到的package个是code个.包是一个文件夹,里面有python(.py)文件,通常有__init__.py个文件(如果不说namespace packages个,那就有点特殊了).

我会怎么做?

  • 首先,重命名您的主包文件夹.您已经在pyproject中将项目命名为myscript(因此您会将其与pip install myscript一起安装),但是文件 struct 将暗示import namecode;因此您需要将其命名为import code.myscript(代码是主包).我将项目名称更改为本例中的myproj,方法是将pyproject t.toml中的名称和./code文件夹中的名称更改为./myproj

  • 其次,对我来说"Package-Data"的名称告诉我它是package内部的数据../resources不是一个包,因为它不包含任何python文件.如果你在那里加一个空的__init__.py,它就会变成一个Package.但是在pyproject t.toml中还有另一个问题:您的包应该在一个名为./resources的文件夹下找到,但实际上它在根文件夹(.)中.因此,你要么改where = ['src', '.'](这会产生新的问题),要么把./resources改成./resources/resources,但你也可以做得更容易(第三点)

  • 第三,您可以通过将打包的数据文件inside放入(./myproj)来简化操作.这是比较常见的做法,也让pip使用您的代码在site-packages/myproj内部安装资源,这很好(尽管也有其他可能性).因此,我建议对pyproject t.toml进行以下更改:

[project]
name = "myproj" # <-- this changed
version = "0.0.1"

[tool.setuptools.packages.find]
where = ["src"] # <-- this changed

[tool.setuptools.package-data]
"*" = ["*.*"] # <-- this changed

然后将文件夹 struct 设置为

? <project root>/
├─? pyproject.toml
└─? src/
  └─? myproj/
    ├─? __init__.py
    ├─? __assets__/ # non-code files here
    │ └─? code1.jar     
    └─? myscript.py

这将创建一个具有以下文件夹 struct 的轮子:

└─? myproj-0.0.1-py3-none-any/
  └─? myproj/
    ├─? __init__.py
    ├─? __assets__/
    │ └─? code1.jar
    └─? myscript.py

Python相关问答推荐

如何在where或过滤器方法中使用SQLAlchemy hybrid_Property?

aiohTTP与pytest的奇怪行为

不同数据类型的Python成员变量不会在具有相同优先级的不同线程中更新

每个组每第n行就有Pandas

无法导入已安装的模块

已删除的构造函数调用另一个构造函数

将轨迹优化问题描述为NLP.如何用Gekko解决这个问题?当前面临异常:@错误:最大方程长度错误

计算所有前面行(当前行)中列的值

分组数据并删除重复数据

如何将ctyles.POINTER(ctyles.c_float)转换为int?

根据不同列的值在收件箱中移动数据

2D空间中的反旋算法

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

对所有子图应用相同的轴格式

在含噪声的3D点网格中识别4连通点模式

移动条情节旁边的半小提琴情节在海运

不允许访问非IPM文件夹

判断solve_ivp中的事件

从列表中获取n个元素,其中list [i][0]== value''

如何获取Python synsets列表的第一个内容?