pypaperless-cli2 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pypaperless_cli2-0.1.0/LICENSE +22 -0
- pypaperless_cli2-0.1.0/PKG-INFO +174 -0
- pypaperless_cli2-0.1.0/README.md +151 -0
- pypaperless_cli2-0.1.0/pyproject.toml +31 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/__init__.py +0 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/api.py +16 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/app.py +186 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/__init__.py +6 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/auth.py +166 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/__init__.py +14 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/edit.py +159 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/commands/document/show.py +120 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/config/__init__.py +2 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/config/account.py +50 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/config/config.py +274 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/const.py +7 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/py.typed +0 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/__init__.py +1 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/__init__.py +22 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/custom_field.py +66 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/helpers/__init__.py +3 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/helpers/strtobool.py +19 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/converters/tag.py +32 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/groups.py +39 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/highlighter.py +11 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/types.py +27 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/__init__.py +42 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/custom_field.py +32 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/document.py +27 -0
- pypaperless_cli2-0.1.0/src/pypaperless_cli/utils/validators/tag.py +31 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Marcel Brückner
|
|
4
|
+
Copyright (c) 2026 Julian Pirner (pypaperless-cli2 fork)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pypaperless-cli2
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Command-line interface for Paperless-ngx (fork of pypaperless-cli, updated for pypaperless 5.x / Paperless-ngx 3.x)
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Author: Marcel Brückner
|
|
7
|
+
Author-email: marcelbrueckner@users.noreply.github.com
|
|
8
|
+
Requires-Python: >=3.12,<4.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: arrow (>=1.3.0,<2.0.0)
|
|
14
|
+
Requires-Dist: cyclopts (>=2.5.0,<3.0.0)
|
|
15
|
+
Requires-Dist: httpx (>=0.27.0,<0.28.0)
|
|
16
|
+
Requires-Dist: pypaperless (>=5.1.0,<6.0.0)
|
|
17
|
+
Requires-Dist: tomlkit (>=0.12.4,<0.13.0)
|
|
18
|
+
Requires-Dist: xdg-base-dirs (>=6.0.1,<7.0.0)
|
|
19
|
+
Project-URL: Homepage, https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2
|
|
20
|
+
Project-URL: Repository, https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# paperless-ngx-cli (pypaperless-cli2)
|
|
24
|
+
|
|
25
|
+
Paperless-ngx Command-Line Interface
|
|
26
|
+
|
|
27
|
+
This is a fork of [Marcel Brückner's `pypaperless-cli`](https://github.com/marcelbrueckner/paperless-ngx-cli), republished as `pypaperless-cli2` with the `pypaperless` dependency updated to `^5.1.0` for compatibility with Paperless-ngx ≥3.0 (which rejects the older API versions requested by `pypaperless` 4.x with `406 Not Acceptable`). The `pngx` command and all usage below are unchanged from upstream.
|
|
28
|
+
|
|
29
|
+
I've recently started a project to collect scripts around Paperless-ngx ([paperless.sh](https://paperless.sh)). It turned out - surprise - to be very tedious to write a separate [script](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/post-consumption/content-matching/pngx-update-document.py) [each](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum.py) [time](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum-of-differences.py) I need to work with Paperless-ngx's API.
|
|
30
|
+
I was looking for a way to easily update certain fields of my documents but without the overhead of "manually" calling API endpoints each time.
|
|
31
|
+
I wrapped things in simple python scripts which eventually became this tool which essentially ~~is~~ will become Paperless-ngx at your command-line.
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
This very first public release currently only allows you to retrieve information or update certain fields of your existing documents (with more to come in the future).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Run pngx -h for help
|
|
39
|
+
$ pngx [ command ] [ subcommand ] [ arguments and parameters ]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Log in to your Paperless-ngx instance which will be used in subsequent commands.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Log in to the given host and save account credentials as default
|
|
46
|
+
$ pngx auth login https://paperless.example.com --ask-token
|
|
47
|
+
# Delete saved credentials from disk
|
|
48
|
+
$ pngx auth logout
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Show details of a document with specific ID
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Run pngx document show -h for help
|
|
55
|
+
$ pngx document show <ID>
|
|
56
|
+
Title 2024-01-10_RE12345678
|
|
57
|
+
ID 400
|
|
58
|
+
ASN None
|
|
59
|
+
Created 2024-01-10
|
|
60
|
+
...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Update a document's title and correspondent.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Set document title to "My new document title" and set specific correspondent
|
|
67
|
+
$ pngx document edit <ID> --title "My new document title" --correspondent <CORRESPONDENT_ID>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Assign or unassign a document's tags.
|
|
71
|
+
|
|
72
|
+
Tags can be specified by ID or the *exact* name. If your tag name contains spaces, wrap it in quotes.
|
|
73
|
+
|
|
74
|
+
You can add and remove multiple tags at once, separated by space.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Add or remove one or multiple tags to/from a document given the ID or _exact_ name
|
|
78
|
+
$ pngx document edit <ID> --add-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
|
|
79
|
+
$ pngx document edit <ID> --remove-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Add, update or remove custom fields.
|
|
83
|
+
|
|
84
|
+
Similar to tags, custom fields can be specified by ID or the *exact* name, which must be quoted if it contains spaces.
|
|
85
|
+
In addition, custom fields can have a value that can be passed in a KEY=VALUE style. Make sure your value adheres to the custom field's type. If your custom field name contains an equal sign, refer to it by its ID.
|
|
86
|
+
|
|
87
|
+
You can add and remove multiple custom fields at once, separated by space.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Add/Update or remove custom field given the ID or _exact_ name
|
|
91
|
+
$ pngx document edit <ID> --add-custom-fields <ID|EXACT_NAME>[=VALUE] [<ID|EXACT_NAME>[=VALUE]]
|
|
92
|
+
$ pngx document edit <ID> --remove-custom-fields <ID|EXACT_NAME> [<ID|EXACT_NAME>]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuration
|
|
96
|
+
|
|
97
|
+
The Paperless-ngx CLI client can be configured in a variety of ways.
|
|
98
|
+
In order of precedence from lowest (most easily overridden) to highest (overrides all others), it offers the following configuration sources:
|
|
99
|
+
|
|
100
|
+
* applications defaults
|
|
101
|
+
* configuration file
|
|
102
|
+
* environment variables
|
|
103
|
+
* command-line parameters
|
|
104
|
+
|
|
105
|
+
### Application defaults
|
|
106
|
+
|
|
107
|
+
There's only one application default:
|
|
108
|
+
|
|
109
|
+
* the CLI client configuration file (which defaults to `$XDG_CONFIG_HOME/pngx/pngx.toml`[^1])
|
|
110
|
+
|
|
111
|
+
[^1]: In case you don't know about the *XDG Base Directory Specification*, check out [their docs](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
|
112
|
+
|
|
113
|
+
### Configuration file
|
|
114
|
+
|
|
115
|
+
The Paperless-ngx CLI client can read all basic configuration (the Paperless-ngx server's authentication information) from its configuration file (`pngx.toml`). A custom file path can be specified via:
|
|
116
|
+
|
|
117
|
+
* command-line parameter (`--config`)
|
|
118
|
+
* environment variable (`$PNGX_CONFIG`)
|
|
119
|
+
|
|
120
|
+
If both are specified, the command-line parameter takes precedence. Otherwise, it uses the first `pngx.toml` file found at these locations in order:
|
|
121
|
+
|
|
122
|
+
* `$PWD/pngx.toml`
|
|
123
|
+
* `$XDG_CONFIG_HOME/pngx/pngx.toml` (application default)
|
|
124
|
+
|
|
125
|
+
If no configuration file can be found, it will be created at the application default location.
|
|
126
|
+
|
|
127
|
+
Run `pngx --show-config` to get the configuration file path in use.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Default configuration path if no pngx.toml exists in current working directory
|
|
131
|
+
$ pngx --show-config
|
|
132
|
+
/Users/marcelbrueckner/.config/pngx/pngx.toml
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Obviously, you can't specify a configuration path within the configuration file itself.
|
|
136
|
+
|
|
137
|
+
### Environment variables
|
|
138
|
+
|
|
139
|
+
If you don't want your credentials to be stored on disk, you can use environment variables or ad-hoc session parameters (see command-line below)
|
|
140
|
+
|
|
141
|
+
Environment variables have a higher precedence than entries in `pngx.toml`. Existing environment variables override corresponding values in your configuration file. If you can't connect to your Paperless-ngx instance, make sure you don't have accidentially mixed values from your configuration file and environment.
|
|
142
|
+
|
|
143
|
+
* `PNGX_HOST`
|
|
144
|
+
* `PNGX_USER`
|
|
145
|
+
* `PNGX_TOKEN`
|
|
146
|
+
|
|
147
|
+
* `PNGX_CONFIG`
|
|
148
|
+
|
|
149
|
+
### Command-line parameters
|
|
150
|
+
|
|
151
|
+
You can use the command-line to log in to your Paperless-ngx instance. The credentials provided will be saved to your configuration file.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Store your credentials for subsequent usage
|
|
155
|
+
# Your credentials might end up in your shell history, so be cautious!
|
|
156
|
+
|
|
157
|
+
# Don't do that
|
|
158
|
+
$ pngx auth login --host=https://paperless.example.com --user=username --password=password
|
|
159
|
+
# Use this instead
|
|
160
|
+
$ pngx auth login --host=https://paperless.example.com --user=username --ask-password|--ask-token
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
If you don't want your credentials saved to file, use them as ad-hoc session parameters.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
$ pngx --host=https://paperless.example.com --user=username --ask-password|--ask-token auth show
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Caveats
|
|
170
|
+
|
|
171
|
+
Paperless-ngx CLI allows you to add servers whose API can be accessed without authentication. However, the underlying `pypaperless` library this CLI is using doesn't look like it supports anything else than token authentication. I guess that you will likely run into errors if you don't use token authentication on your Paperless-ngx server instance. Maybe a token can be generated while using remote user auth, but it's untested at this point.
|
|
172
|
+
|
|
173
|
+
This fork has been checked against Paperless-ngx 3.0.5; the upstream project was tested against v2.5.3. As with upstream, compatibility depends on the `pypaperless` library tracking whatever HTTP API version Paperless-ngx currently requires.
|
|
174
|
+
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# paperless-ngx-cli (pypaperless-cli2)
|
|
2
|
+
|
|
3
|
+
Paperless-ngx Command-Line Interface
|
|
4
|
+
|
|
5
|
+
This is a fork of [Marcel Brückner's `pypaperless-cli`](https://github.com/marcelbrueckner/paperless-ngx-cli), republished as `pypaperless-cli2` with the `pypaperless` dependency updated to `^5.1.0` for compatibility with Paperless-ngx ≥3.0 (which rejects the older API versions requested by `pypaperless` 4.x with `406 Not Acceptable`). The `pngx` command and all usage below are unchanged from upstream.
|
|
6
|
+
|
|
7
|
+
I've recently started a project to collect scripts around Paperless-ngx ([paperless.sh](https://paperless.sh)). It turned out - surprise - to be very tedious to write a separate [script](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/post-consumption/content-matching/pngx-update-document.py) [each](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum.py) [time](https://github.com/marcelbrueckner/paperless.sh/blob/6cc85b20482e0281d9e26ab82fcaccf34e27a276/scripts/api/custom-field-sum/custom-field-sum-of-differences.py) I need to work with Paperless-ngx's API.
|
|
8
|
+
I was looking for a way to easily update certain fields of my documents but without the overhead of "manually" calling API endpoints each time.
|
|
9
|
+
I wrapped things in simple python scripts which eventually became this tool which essentially ~~is~~ will become Paperless-ngx at your command-line.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
This very first public release currently only allows you to retrieve information or update certain fields of your existing documents (with more to come in the future).
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Run pngx -h for help
|
|
17
|
+
$ pngx [ command ] [ subcommand ] [ arguments and parameters ]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Log in to your Paperless-ngx instance which will be used in subsequent commands.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Log in to the given host and save account credentials as default
|
|
24
|
+
$ pngx auth login https://paperless.example.com --ask-token
|
|
25
|
+
# Delete saved credentials from disk
|
|
26
|
+
$ pngx auth logout
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Show details of a document with specific ID
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Run pngx document show -h for help
|
|
33
|
+
$ pngx document show <ID>
|
|
34
|
+
Title 2024-01-10_RE12345678
|
|
35
|
+
ID 400
|
|
36
|
+
ASN None
|
|
37
|
+
Created 2024-01-10
|
|
38
|
+
...
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Update a document's title and correspondent.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Set document title to "My new document title" and set specific correspondent
|
|
45
|
+
$ pngx document edit <ID> --title "My new document title" --correspondent <CORRESPONDENT_ID>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Assign or unassign a document's tags.
|
|
49
|
+
|
|
50
|
+
Tags can be specified by ID or the *exact* name. If your tag name contains spaces, wrap it in quotes.
|
|
51
|
+
|
|
52
|
+
You can add and remove multiple tags at once, separated by space.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Add or remove one or multiple tags to/from a document given the ID or _exact_ name
|
|
56
|
+
$ pngx document edit <ID> --add-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
|
|
57
|
+
$ pngx document edit <ID> --remove-tags <ID|EXACT_NAME> [ID|EXACT_NAME]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Add, update or remove custom fields.
|
|
61
|
+
|
|
62
|
+
Similar to tags, custom fields can be specified by ID or the *exact* name, which must be quoted if it contains spaces.
|
|
63
|
+
In addition, custom fields can have a value that can be passed in a KEY=VALUE style. Make sure your value adheres to the custom field's type. If your custom field name contains an equal sign, refer to it by its ID.
|
|
64
|
+
|
|
65
|
+
You can add and remove multiple custom fields at once, separated by space.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Add/Update or remove custom field given the ID or _exact_ name
|
|
69
|
+
$ pngx document edit <ID> --add-custom-fields <ID|EXACT_NAME>[=VALUE] [<ID|EXACT_NAME>[=VALUE]]
|
|
70
|
+
$ pngx document edit <ID> --remove-custom-fields <ID|EXACT_NAME> [<ID|EXACT_NAME>]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
The Paperless-ngx CLI client can be configured in a variety of ways.
|
|
76
|
+
In order of precedence from lowest (most easily overridden) to highest (overrides all others), it offers the following configuration sources:
|
|
77
|
+
|
|
78
|
+
* applications defaults
|
|
79
|
+
* configuration file
|
|
80
|
+
* environment variables
|
|
81
|
+
* command-line parameters
|
|
82
|
+
|
|
83
|
+
### Application defaults
|
|
84
|
+
|
|
85
|
+
There's only one application default:
|
|
86
|
+
|
|
87
|
+
* the CLI client configuration file (which defaults to `$XDG_CONFIG_HOME/pngx/pngx.toml`[^1])
|
|
88
|
+
|
|
89
|
+
[^1]: In case you don't know about the *XDG Base Directory Specification*, check out [their docs](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
|
|
90
|
+
|
|
91
|
+
### Configuration file
|
|
92
|
+
|
|
93
|
+
The Paperless-ngx CLI client can read all basic configuration (the Paperless-ngx server's authentication information) from its configuration file (`pngx.toml`). A custom file path can be specified via:
|
|
94
|
+
|
|
95
|
+
* command-line parameter (`--config`)
|
|
96
|
+
* environment variable (`$PNGX_CONFIG`)
|
|
97
|
+
|
|
98
|
+
If both are specified, the command-line parameter takes precedence. Otherwise, it uses the first `pngx.toml` file found at these locations in order:
|
|
99
|
+
|
|
100
|
+
* `$PWD/pngx.toml`
|
|
101
|
+
* `$XDG_CONFIG_HOME/pngx/pngx.toml` (application default)
|
|
102
|
+
|
|
103
|
+
If no configuration file can be found, it will be created at the application default location.
|
|
104
|
+
|
|
105
|
+
Run `pngx --show-config` to get the configuration file path in use.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Default configuration path if no pngx.toml exists in current working directory
|
|
109
|
+
$ pngx --show-config
|
|
110
|
+
/Users/marcelbrueckner/.config/pngx/pngx.toml
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Obviously, you can't specify a configuration path within the configuration file itself.
|
|
114
|
+
|
|
115
|
+
### Environment variables
|
|
116
|
+
|
|
117
|
+
If you don't want your credentials to be stored on disk, you can use environment variables or ad-hoc session parameters (see command-line below)
|
|
118
|
+
|
|
119
|
+
Environment variables have a higher precedence than entries in `pngx.toml`. Existing environment variables override corresponding values in your configuration file. If you can't connect to your Paperless-ngx instance, make sure you don't have accidentially mixed values from your configuration file and environment.
|
|
120
|
+
|
|
121
|
+
* `PNGX_HOST`
|
|
122
|
+
* `PNGX_USER`
|
|
123
|
+
* `PNGX_TOKEN`
|
|
124
|
+
|
|
125
|
+
* `PNGX_CONFIG`
|
|
126
|
+
|
|
127
|
+
### Command-line parameters
|
|
128
|
+
|
|
129
|
+
You can use the command-line to log in to your Paperless-ngx instance. The credentials provided will be saved to your configuration file.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Store your credentials for subsequent usage
|
|
133
|
+
# Your credentials might end up in your shell history, so be cautious!
|
|
134
|
+
|
|
135
|
+
# Don't do that
|
|
136
|
+
$ pngx auth login --host=https://paperless.example.com --user=username --password=password
|
|
137
|
+
# Use this instead
|
|
138
|
+
$ pngx auth login --host=https://paperless.example.com --user=username --ask-password|--ask-token
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
If you don't want your credentials saved to file, use them as ad-hoc session parameters.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
$ pngx --host=https://paperless.example.com --user=username --ask-password|--ask-token auth show
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Caveats
|
|
148
|
+
|
|
149
|
+
Paperless-ngx CLI allows you to add servers whose API can be accessed without authentication. However, the underlying `pypaperless` library this CLI is using doesn't look like it supports anything else than token authentication. I guess that you will likely run into errors if you don't use token authentication on your Paperless-ngx server instance. Maybe a token can be generated while using remote user auth, but it's untested at this point.
|
|
150
|
+
|
|
151
|
+
This fork has been checked against Paperless-ngx 3.0.5; the upstream project was tested against v2.5.3. As with upstream, compatibility depends on the `pypaperless` library tracking whatever HTTP API version Paperless-ngx currently requires.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "pypaperless-cli2"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Command-line interface for Paperless-ngx (fork of pypaperless-cli, updated for pypaperless 5.x / Paperless-ngx 3.x)"
|
|
5
|
+
authors = ["Marcel Brückner <marcelbrueckner@users.noreply.github.com>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
homepage = "https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2"
|
|
8
|
+
repository = "https://gitlab.jpi-it.com/j.pirner/pypaperless-cli2"
|
|
9
|
+
packages = [{include = "pypaperless_cli", from = "src"}]
|
|
10
|
+
|
|
11
|
+
[tool.poetry.scripts]
|
|
12
|
+
pngx = "pypaperless_cli.app:launch"
|
|
13
|
+
|
|
14
|
+
[tool.poetry.dependencies]
|
|
15
|
+
python = "^3.12"
|
|
16
|
+
arrow = "^1.3.0"
|
|
17
|
+
httpx = "^0.27.0"
|
|
18
|
+
cyclopts = "^2.5.0"
|
|
19
|
+
tomlkit = "^0.12.4"
|
|
20
|
+
xdg-base-dirs = "^6.0.1"
|
|
21
|
+
pypaperless = "^5.1.0"
|
|
22
|
+
|
|
23
|
+
[tool.poetry.group.dev.dependencies]
|
|
24
|
+
mypy = "^1.9.0"
|
|
25
|
+
pytest = "^8.1.1"
|
|
26
|
+
httpx = {extras = ["cli"], version = "^0.27.0"}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["poetry-core"]
|
|
31
|
+
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Paperless API client"""
|
|
2
|
+
|
|
3
|
+
from aiohttp import ClientSession
|
|
4
|
+
from pypaperless import Paperless
|
|
5
|
+
|
|
6
|
+
from pypaperless_cli.config import config as appconfig
|
|
7
|
+
|
|
8
|
+
class PaperlessAsyncAPI(Paperless):
|
|
9
|
+
"""Represent the Paperless API"""
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
session = ClientSession(headers={"User-Agent": f"pypaperless-cli/0.1-dev (https://github.com/marcelbrueckner/paperless-ngx-cli)"})
|
|
13
|
+
super().__init__(appconfig.current.host, appconfig.current.token, session=session)
|
|
14
|
+
|
|
15
|
+
# Don't care about warnings
|
|
16
|
+
self.logger.setLevel("ERROR")
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Annotated, Optional
|
|
5
|
+
|
|
6
|
+
from cyclopts import App, Parameter
|
|
7
|
+
from cyclopts.types import Path
|
|
8
|
+
from cyclopts.exceptions import format_cyclopts_error
|
|
9
|
+
|
|
10
|
+
from rich.prompt import Prompt
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
|
|
13
|
+
from pypaperless_cli.config import config as appconfig
|
|
14
|
+
from pypaperless_cli.utils import groups, validators
|
|
15
|
+
from pypaperless_cli.commands import (
|
|
16
|
+
auth,
|
|
17
|
+
document,
|
|
18
|
+
)
|
|
19
|
+
from pypaperless_cli.utils.types import (
|
|
20
|
+
account_alias,
|
|
21
|
+
URL
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# BASIC APP STRUCTURE
|
|
26
|
+
# Loosely based on the Paperless-ngx API and web interface structure
|
|
27
|
+
# https://cyclopts.readthedocs.io/en/latest/commands.html
|
|
28
|
+
# https://docs.paperless-ngx.com/api/
|
|
29
|
+
|
|
30
|
+
app = App(
|
|
31
|
+
name="pngx",
|
|
32
|
+
help="Command-line interface for Paperless-ngx 🌱",
|
|
33
|
+
group_commands=groups.commands,
|
|
34
|
+
version_flags=["--version", "-v"]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Change the group of "--help" and "--version" to the implicit "Help" group.
|
|
38
|
+
app["--help"].group = "Help"
|
|
39
|
+
app["--version"].group = "Help"
|
|
40
|
+
|
|
41
|
+
app.command(auth)
|
|
42
|
+
app.command(document)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# CLI HELP
|
|
47
|
+
#
|
|
48
|
+
|
|
49
|
+
app.meta["--help"].group = "Help"
|
|
50
|
+
app.meta["--version"].group = "Help"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# CLI entry-point
|
|
55
|
+
#
|
|
56
|
+
|
|
57
|
+
# Set up configuration before running the actual application
|
|
58
|
+
@app.meta.default()
|
|
59
|
+
def main(
|
|
60
|
+
*tokens: Annotated[str, Parameter(show=False, allow_leading_hyphen=True)],
|
|
61
|
+
host: Annotated[Optional[URL], Parameter(
|
|
62
|
+
env_var=['PNGX_HOST'],
|
|
63
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc],
|
|
64
|
+
)] = None,
|
|
65
|
+
user: Annotated[Optional[str], Parameter(
|
|
66
|
+
env_var = ['PNGX_USER'],
|
|
67
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc],
|
|
68
|
+
validator = validators.not_empty,
|
|
69
|
+
)] = None,
|
|
70
|
+
password: Annotated[Optional[str], Parameter(
|
|
71
|
+
env_var = ['PNGX_PASSWORD'],
|
|
72
|
+
negative = "--ask-password",
|
|
73
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
|
|
74
|
+
)] = None,
|
|
75
|
+
ask_password: Annotated[Optional[bool], Parameter(
|
|
76
|
+
show = False,
|
|
77
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
|
|
78
|
+
)] = None,
|
|
79
|
+
token: Annotated[Optional[str], Parameter(
|
|
80
|
+
env_var = ['PNGX_TOKEN'],
|
|
81
|
+
negative = "--ask-token",
|
|
82
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token],
|
|
83
|
+
)] = None,
|
|
84
|
+
ask_token: Annotated[Optional[bool], Parameter(
|
|
85
|
+
show = False,
|
|
86
|
+
group = [groups.meta_parameters, groups.meta_parameters_adhoc, groups.password_xor_token]
|
|
87
|
+
)] = None,
|
|
88
|
+
config_file: Annotated[Optional[Path], Parameter(
|
|
89
|
+
name = "--config",
|
|
90
|
+
env_var = ['PNGX_CONFIG'],
|
|
91
|
+
group = [groups.meta_parameters, groups.meta_parameters_specific]
|
|
92
|
+
)] = None,
|
|
93
|
+
use_account: Annotated[Optional[account_alias], Parameter(
|
|
94
|
+
name = "--use",
|
|
95
|
+
group = [groups.meta_parameters, groups.meta_parameters_specific],
|
|
96
|
+
validator = validators.starts_with_ascii_letters
|
|
97
|
+
)] = None,
|
|
98
|
+
show_config: Annotated[Optional[bool], Parameter(
|
|
99
|
+
group = [groups.meta_parameters, "Help"],
|
|
100
|
+
negative = [],
|
|
101
|
+
show_default = False
|
|
102
|
+
)] = False,
|
|
103
|
+
) -> None:
|
|
104
|
+
|
|
105
|
+
"""Initiate CLI
|
|
106
|
+
|
|
107
|
+
Parameters
|
|
108
|
+
----------
|
|
109
|
+
host: str
|
|
110
|
+
The URL of your Paperless-ngx host, possibly including a custom port and/or script path.
|
|
111
|
+
user: str
|
|
112
|
+
Username
|
|
113
|
+
password: str
|
|
114
|
+
Password. Will be used to request an API token only.
|
|
115
|
+
token: str
|
|
116
|
+
API token.
|
|
117
|
+
config_file: Path
|
|
118
|
+
Path to configuration file.
|
|
119
|
+
use_account: str
|
|
120
|
+
Name (alias) of an account that should be used.
|
|
121
|
+
|
|
122
|
+
If an account with the given alias exists, its credentials will be re-used.
|
|
123
|
+
If not specified, the default account will be used (if any).
|
|
124
|
+
show_config: bool
|
|
125
|
+
Show path of the configuration file in use.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
if ask_password:
|
|
130
|
+
password = Prompt.ask("What's your password?", password=True)
|
|
131
|
+
|
|
132
|
+
elif ask_token:
|
|
133
|
+
token = Prompt.ask("What's your API token?", password=True)
|
|
134
|
+
|
|
135
|
+
# Parse configuration
|
|
136
|
+
try:
|
|
137
|
+
appconfig.load(config_file, use_account)
|
|
138
|
+
except ValueError as e:
|
|
139
|
+
Console().print(format_cyclopts_error(e))
|
|
140
|
+
sys.exit(1)
|
|
141
|
+
|
|
142
|
+
if show_config:
|
|
143
|
+
print(appconfig.filepath.absolute())
|
|
144
|
+
sys.exit(0)
|
|
145
|
+
|
|
146
|
+
# Add ad-hoc configuration
|
|
147
|
+
if host and not tokens[:2] == ('auth', 'login'):
|
|
148
|
+
try:
|
|
149
|
+
appconfig.add_account(
|
|
150
|
+
host = host,
|
|
151
|
+
user = user,
|
|
152
|
+
password = password,
|
|
153
|
+
token = token,
|
|
154
|
+
alias = "__adhoc__"
|
|
155
|
+
)
|
|
156
|
+
except ValueError as e:
|
|
157
|
+
Console().print(format_cyclopts_error(e))
|
|
158
|
+
sys.exit(1)
|
|
159
|
+
|
|
160
|
+
elif tokens[:2] == ('auth', 'login'):
|
|
161
|
+
# Pass credentials to login function
|
|
162
|
+
if host:
|
|
163
|
+
tokens += (host,)
|
|
164
|
+
if user:
|
|
165
|
+
tokens += ("--user", user)
|
|
166
|
+
if password:
|
|
167
|
+
tokens += ("--password", password)
|
|
168
|
+
if token:
|
|
169
|
+
tokens += ("--token", token)
|
|
170
|
+
|
|
171
|
+
elif not appconfig.list():
|
|
172
|
+
Console().print(format_cyclopts_error("No accounts configured that can be used."))
|
|
173
|
+
sys.exit(1)
|
|
174
|
+
|
|
175
|
+
# Now run the actual app
|
|
176
|
+
try:
|
|
177
|
+
app(tokens)
|
|
178
|
+
except ValueError as e:
|
|
179
|
+
Console().print(format_cyclopts_error(e))
|
|
180
|
+
sys.exit(1)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def launch() -> None:
|
|
184
|
+
"""Run commands."""
|
|
185
|
+
|
|
186
|
+
app.meta()
|