You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: python/python-packaging.md
+68Lines changed: 68 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -36,3 +36,71 @@ setup(
36
36
setup_requires=["setuptools>=62.1.0"],
37
37
)
38
38
```
39
+
40
+
## Structure of package with CLI scripts
41
+
42
+
Example structure:
43
+
44
+
```
45
+
my_package/
46
+
my_package/
47
+
__init__.py
48
+
cli_scripts.py
49
+
setup.py
50
+
```
51
+
52
+
Let's assume your `__init__.py` looks like this (as a side note, I'd recommend moving the classes defined in there to a separate file, and then simply importing that file in the `__init__`):
53
+
54
+
```python
55
+
classTest(object):
56
+
57
+
def__init__(self, a)
58
+
self.a = a
59
+
60
+
def__call__(self):
61
+
print(self.a)
62
+
```
63
+
64
+
Now there is an additional file inside the package that utilizes the stuff you implemented in the package, let's call it `cli_scripts.py`:
65
+
66
+
```python
67
+
import argparse
68
+
69
+
from my_package import Test
70
+
71
+
defparse_args():
72
+
parser = argparse.ArgumentParser()
73
+
parser.add_argument("a", type=int, help="Just an example argument")
74
+
return parser.parse_args()
75
+
76
+
defdemonstration():
77
+
args = parse_args()
78
+
t = Test(a=args.a)
79
+
t()
80
+
```
81
+
My suggestion now is to utilize the `console_scripts` entry point inside `setup.py`, which could now look something like this:
Now when you run `pip install .` inside the top-level `my_package` folder, your package will be installed. The `entry_points` automatically generate an executable for you, that you can now call with the name you gave it inside `setup.py`, in this example `mypkg`. This means you can now run `mypkg 5` and this will call `demonstration()`.
99
+
100
+
This way:
101
+
102
+
- you do not need to handle any `__main__` files
103
+
- you can give your script a meaningful name
104
+
- you don't need to care whether your script is executable, or specify to run the script with python
105
+
- you can have as many of these as you want inside the list `entry_points`
106
+
- it forces you to write functions that you could also call from other modules, instead of the `__main__`
0 commit comments