librepost-app 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.
- librepost_app-0.1.0/LICENSE +21 -0
- librepost_app-0.1.0/PKG-INFO +195 -0
- librepost_app-0.1.0/README.md +159 -0
- librepost_app-0.1.0/pyproject.toml +103 -0
- librepost_app-0.1.0/pyproject.toml.orig +83 -0
- librepost_app-0.1.0/src/librepost/__init__.py +3 -0
- librepost_app-0.1.0/src/librepost/__main__.py +3 -0
- librepost_app-0.1.0/src/librepost/cli.py +301 -0
- librepost_app-0.1.0/src/librepost/environments.py +71 -0
- librepost_app-0.1.0/src/librepost/httpfile.py +205 -0
- librepost_app-0.1.0/src/librepost/leakcheck.py +182 -0
- librepost_app-0.1.0/src/librepost/py.typed +0 -0
- librepost_app-0.1.0/src/librepost/runner.py +118 -0
- librepost_app-0.1.0/src/librepost/secretstore.py +73 -0
- librepost_app-0.1.0/src/librepost/server.py +312 -0
- librepost_app-0.1.0/src/librepost/static/app.css +311 -0
- librepost_app-0.1.0/src/librepost/static/app.js +62 -0
- librepost_app-0.1.0/src/librepost/static/icon.svg +1 -0
- librepost_app-0.1.0/src/librepost/static/vendor/htmx-2.0.11.min.js +1 -0
- librepost_app-0.1.0/src/librepost/static/vendor/htmx-LICENSE.txt +13 -0
- librepost_app-0.1.0/src/librepost/template.py +95 -0
- librepost_app-0.1.0/src/librepost/templates/editor.html +38 -0
- librepost_app-0.1.0/src/librepost/templates/empty.html +6 -0
- librepost_app-0.1.0/src/librepost/templates/error.html +1 -0
- librepost_app-0.1.0/src/librepost/templates/index.html +49 -0
- librepost_app-0.1.0/src/librepost/templates/response.html +41 -0
- librepost_app-0.1.0/src/librepost/templates/status.html +1 -0
- librepost_app-0.1.0/src/librepost/templates/tree.html +20 -0
- librepost_app-0.1.0/src/librepost/workspace.py +135 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ag3nt Sc4rn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: librepost-app
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A free, local-first API client. Requests live as plain .http files in your git repo; secrets stay in your keychain.
|
|
5
|
+
Keywords: api,http,rest,client,postman-alternative,http-file,git,local-first
|
|
6
|
+
Author: Ag3nt Sc4rn
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: src/librepost/static/vendor/htmx-LICENSE.txt
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Environment :: Web Environment
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Software Development :: Testing
|
|
23
|
+
Requires-Dist: httpx>=0.27
|
|
24
|
+
Requires-Dist: jinja2>=3.1
|
|
25
|
+
Requires-Dist: keyring>=25.0
|
|
26
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
27
|
+
Requires-Dist: rich>=13.7
|
|
28
|
+
Requires-Dist: starlette>=0.40
|
|
29
|
+
Requires-Dist: typer>=0.12
|
|
30
|
+
Requires-Dist: uvicorn>=0.30
|
|
31
|
+
Requires-Python: >=3.11
|
|
32
|
+
Project-URL: Homepage, https://github.com/ag3ntsc4rn/librepost
|
|
33
|
+
Project-URL: Issues, https://github.com/ag3ntsc4rn/librepost/issues
|
|
34
|
+
Project-URL: Changelog, https://github.com/ag3ntsc4rn/librepost/blob/main/CHANGELOG.md
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# librepost
|
|
38
|
+
|
|
39
|
+
[](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml)
|
|
40
|
+
[](https://pypi.org/project/librepost-app/)
|
|
41
|
+
[](https://pypi.org/project/librepost-app/)
|
|
42
|
+
[](https://github.com/ag3ntsc4rn/librepost/blob/main/LICENSE)
|
|
43
|
+
|
|
44
|
+
**A free, local-first API client.** Your requests are plain `.http` files in your git repo.
|
|
45
|
+
Your secrets stay in your OS keychain. No account, no cloud, no telemetry, and nothing
|
|
46
|
+
installed anywhere except the package itself.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uvx librepost-app ui # or: uv tool install librepost-app && librepost ui
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
That opens a Postman-style UI in your browser, served from your own machine. (On PyPI the
|
|
53
|
+
package is `librepost-app`; once installed, the command is `librepost`.)
|
|
54
|
+
|
|
55
|
+
## Why
|
|
56
|
+
|
|
57
|
+
API clients have become cloud platforms: sign-ins, team workspaces, sync, and desktop apps
|
|
58
|
+
that change your system without asking (see [postman-app-support#14370](https://github.com/postmanlabs/postman-app-support/issues/14370)).
|
|
59
|
+
librepost goes the other way:
|
|
60
|
+
|
|
61
|
+
- **Requests are files.** One folder, plain text, diffable in pull requests. The format is
|
|
62
|
+
the `.http` format used by the JetBrains HTTP Client and the VS Code REST Client, so your
|
|
63
|
+
collection also works in those tools.
|
|
64
|
+
- **Secrets are references.** Write `{{secret:keychain/github-token}}`; the value is read from
|
|
65
|
+
the keychain only when a request is sent, and is masked everywhere on screen.
|
|
66
|
+
- **Leaks are caught.** `librepost check` (also a pre-commit hook) flags tokens and literal
|
|
67
|
+
credentials before they reach git.
|
|
68
|
+
- **It stays in its lane.** librepost reads and writes `.http` files in the folder you point it
|
|
69
|
+
at, and nothing else. No auto-updates, no plugins, no background services.
|
|
70
|
+
|
|
71
|
+
## Quick start
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
librepost init my-api # example env file + requests; gitignores the private env file
|
|
75
|
+
cd my-api
|
|
76
|
+
librepost ui # opens http://127.0.0.1:8765/?token=...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or from the terminal:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
librepost run requests/example.http --name post-example --env dev -v
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Requests
|
|
86
|
+
|
|
87
|
+
```http
|
|
88
|
+
@apiVersion = v2
|
|
89
|
+
|
|
90
|
+
# @name create-user
|
|
91
|
+
POST {{baseUrl}}/{{apiVersion}}/users
|
|
92
|
+
Content-Type: application/json
|
|
93
|
+
Authorization: Bearer {{token}}
|
|
94
|
+
|
|
95
|
+
{"name": "Ada", "requestId": "{{$uuid}}"}
|
|
96
|
+
|
|
97
|
+
###
|
|
98
|
+
|
|
99
|
+
# @name list-users
|
|
100
|
+
GET {{baseUrl}}/{{apiVersion}}/users?page=1
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- Requests are separated by `###`; `# @name` gives one a name.
|
|
104
|
+
- `@name = value` lines define file variables.
|
|
105
|
+
- Built-in values: `{{$uuid}}`, `{{$timestamp}}`, `{{$isoTimestamp}}`, `{{$randomInt}}`.
|
|
106
|
+
- Response handler scripts (`> {% ... %}`) are kept intact when you save, but are not run.
|
|
107
|
+
|
|
108
|
+
## Environments
|
|
109
|
+
|
|
110
|
+
Same format as the JetBrains HTTP Client:
|
|
111
|
+
|
|
112
|
+
| File | Commit it? | Holds |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `http-client.env.json` | yes | shared, non-secret values per environment |
|
|
115
|
+
| `http-client.private.env.json` | **no** (gitignored by `librepost init`) | per-machine overrides |
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"$shared": {"apiVersion": "v2"},
|
|
120
|
+
"dev": {"baseUrl": "https://dev.example.com", "token": "{{secret:keychain/dev-token}}"},
|
|
121
|
+
"prod": {"baseUrl": "https://api.example.com", "token": "{{secret:keychain/prod-token}}"}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Secrets
|
|
126
|
+
|
|
127
|
+
| Reference | Value comes from |
|
|
128
|
+
|---|---|
|
|
129
|
+
| `{{secret:keychain/<name>}}` | the OS keychain: macOS Keychain, Windows Credential Manager, or Secret Service (GNOME Keyring, KWallet) on Linux |
|
|
130
|
+
| `{{secret:env/<NAME>}}` | an environment variable, handy in CI and on headless machines |
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
librepost secret set dev-token # prompts without echoing
|
|
134
|
+
librepost secret delete dev-token
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Secret values are masked (`••••••`) in the request preview, response headers and response
|
|
138
|
+
body (APIs often echo credentials back), and in error messages.
|
|
139
|
+
|
|
140
|
+
## Leak check
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
librepost check # exit code 1 if anything looks like a secret
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
It looks for known token formats (GitHub, AWS, Slack, Stripe, Google, OpenAI, Anthropic, JWTs,
|
|
147
|
+
private keys), literal values in `Authorization`, `Cookie` and API-key headers, literal
|
|
148
|
+
passwords and tokens in `http-client.env.json`, and a private env file that isn't gitignored.
|
|
149
|
+
|
|
150
|
+
As a [pre-commit](https://pre-commit.com) hook:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
- repo: https://github.com/ag3ntsc4rn/librepost
|
|
154
|
+
rev: v0.1.0
|
|
155
|
+
hooks:
|
|
156
|
+
- id: librepost-check
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## How the local UI is protected
|
|
160
|
+
|
|
161
|
+
A local web server that sends HTTP requests for you would be an open door into your network
|
|
162
|
+
for any website you visit, if it weren't locked down. librepost:
|
|
163
|
+
|
|
164
|
+
- listens on `127.0.0.1` only, never on your network;
|
|
165
|
+
- requires the random token printed at startup; the token is swapped for an `HttpOnly`,
|
|
166
|
+
`SameSite=Strict` cookie scoped to that port;
|
|
167
|
+
- rejects any `Host` header other than `127.0.0.1:<port>`/`localhost:<port>`, which blocks
|
|
168
|
+
DNS rebinding;
|
|
169
|
+
- rejects state-changing requests without a same-origin `Origin` header and htmx's request
|
|
170
|
+
header, so other sites can't make it send requests;
|
|
171
|
+
- sends a strict Content-Security-Policy (no inline or third-party scripts), shows response
|
|
172
|
+
bodies only as escaped text, and marks every response `Cache-Control: no-store`.
|
|
173
|
+
|
|
174
|
+
Found a hole? Please report it privately; see [SECURITY.md](SECURITY.md).
|
|
175
|
+
|
|
176
|
+
## Requirements
|
|
177
|
+
|
|
178
|
+
Python 3.11+ (`uvx` will fetch one for you) and a web browser. Git is optional.
|
|
179
|
+
|
|
180
|
+
## Roadmap
|
|
181
|
+
|
|
182
|
+
- Import from Postman collections, curl commands and HAR files
|
|
183
|
+
- A native window (`pip install librepost-app[desktop]`)
|
|
184
|
+
- Git status and commit from the UI
|
|
185
|
+
- Client certificates (mTLS), proxy settings, request history and response diffs
|
|
186
|
+
- More secret providers: 1Password CLI, HashiCorp Vault, `pass`
|
|
187
|
+
|
|
188
|
+
## Contributing
|
|
189
|
+
|
|
190
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
[MIT](LICENSE). The bundled [htmx](https://htmx.org) is under the
|
|
195
|
+
[Zero-Clause BSD](src/librepost/static/vendor/htmx-LICENSE.txt) licence.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# librepost
|
|
2
|
+
|
|
3
|
+
[](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/librepost-app/)
|
|
5
|
+
[](https://pypi.org/project/librepost-app/)
|
|
6
|
+
[](https://github.com/ag3ntsc4rn/librepost/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
**A free, local-first API client.** Your requests are plain `.http` files in your git repo.
|
|
9
|
+
Your secrets stay in your OS keychain. No account, no cloud, no telemetry, and nothing
|
|
10
|
+
installed anywhere except the package itself.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uvx librepost-app ui # or: uv tool install librepost-app && librepost ui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
That opens a Postman-style UI in your browser, served from your own machine. (On PyPI the
|
|
17
|
+
package is `librepost-app`; once installed, the command is `librepost`.)
|
|
18
|
+
|
|
19
|
+
## Why
|
|
20
|
+
|
|
21
|
+
API clients have become cloud platforms: sign-ins, team workspaces, sync, and desktop apps
|
|
22
|
+
that change your system without asking (see [postman-app-support#14370](https://github.com/postmanlabs/postman-app-support/issues/14370)).
|
|
23
|
+
librepost goes the other way:
|
|
24
|
+
|
|
25
|
+
- **Requests are files.** One folder, plain text, diffable in pull requests. The format is
|
|
26
|
+
the `.http` format used by the JetBrains HTTP Client and the VS Code REST Client, so your
|
|
27
|
+
collection also works in those tools.
|
|
28
|
+
- **Secrets are references.** Write `{{secret:keychain/github-token}}`; the value is read from
|
|
29
|
+
the keychain only when a request is sent, and is masked everywhere on screen.
|
|
30
|
+
- **Leaks are caught.** `librepost check` (also a pre-commit hook) flags tokens and literal
|
|
31
|
+
credentials before they reach git.
|
|
32
|
+
- **It stays in its lane.** librepost reads and writes `.http` files in the folder you point it
|
|
33
|
+
at, and nothing else. No auto-updates, no plugins, no background services.
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
librepost init my-api # example env file + requests; gitignores the private env file
|
|
39
|
+
cd my-api
|
|
40
|
+
librepost ui # opens http://127.0.0.1:8765/?token=...
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or from the terminal:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
librepost run requests/example.http --name post-example --env dev -v
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Requests
|
|
50
|
+
|
|
51
|
+
```http
|
|
52
|
+
@apiVersion = v2
|
|
53
|
+
|
|
54
|
+
# @name create-user
|
|
55
|
+
POST {{baseUrl}}/{{apiVersion}}/users
|
|
56
|
+
Content-Type: application/json
|
|
57
|
+
Authorization: Bearer {{token}}
|
|
58
|
+
|
|
59
|
+
{"name": "Ada", "requestId": "{{$uuid}}"}
|
|
60
|
+
|
|
61
|
+
###
|
|
62
|
+
|
|
63
|
+
# @name list-users
|
|
64
|
+
GET {{baseUrl}}/{{apiVersion}}/users?page=1
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- Requests are separated by `###`; `# @name` gives one a name.
|
|
68
|
+
- `@name = value` lines define file variables.
|
|
69
|
+
- Built-in values: `{{$uuid}}`, `{{$timestamp}}`, `{{$isoTimestamp}}`, `{{$randomInt}}`.
|
|
70
|
+
- Response handler scripts (`> {% ... %}`) are kept intact when you save, but are not run.
|
|
71
|
+
|
|
72
|
+
## Environments
|
|
73
|
+
|
|
74
|
+
Same format as the JetBrains HTTP Client:
|
|
75
|
+
|
|
76
|
+
| File | Commit it? | Holds |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `http-client.env.json` | yes | shared, non-secret values per environment |
|
|
79
|
+
| `http-client.private.env.json` | **no** (gitignored by `librepost init`) | per-machine overrides |
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"$shared": {"apiVersion": "v2"},
|
|
84
|
+
"dev": {"baseUrl": "https://dev.example.com", "token": "{{secret:keychain/dev-token}}"},
|
|
85
|
+
"prod": {"baseUrl": "https://api.example.com", "token": "{{secret:keychain/prod-token}}"}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Secrets
|
|
90
|
+
|
|
91
|
+
| Reference | Value comes from |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `{{secret:keychain/<name>}}` | the OS keychain: macOS Keychain, Windows Credential Manager, or Secret Service (GNOME Keyring, KWallet) on Linux |
|
|
94
|
+
| `{{secret:env/<NAME>}}` | an environment variable, handy in CI and on headless machines |
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
librepost secret set dev-token # prompts without echoing
|
|
98
|
+
librepost secret delete dev-token
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Secret values are masked (`••••••`) in the request preview, response headers and response
|
|
102
|
+
body (APIs often echo credentials back), and in error messages.
|
|
103
|
+
|
|
104
|
+
## Leak check
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
librepost check # exit code 1 if anything looks like a secret
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
It looks for known token formats (GitHub, AWS, Slack, Stripe, Google, OpenAI, Anthropic, JWTs,
|
|
111
|
+
private keys), literal values in `Authorization`, `Cookie` and API-key headers, literal
|
|
112
|
+
passwords and tokens in `http-client.env.json`, and a private env file that isn't gitignored.
|
|
113
|
+
|
|
114
|
+
As a [pre-commit](https://pre-commit.com) hook:
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
- repo: https://github.com/ag3ntsc4rn/librepost
|
|
118
|
+
rev: v0.1.0
|
|
119
|
+
hooks:
|
|
120
|
+
- id: librepost-check
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## How the local UI is protected
|
|
124
|
+
|
|
125
|
+
A local web server that sends HTTP requests for you would be an open door into your network
|
|
126
|
+
for any website you visit, if it weren't locked down. librepost:
|
|
127
|
+
|
|
128
|
+
- listens on `127.0.0.1` only, never on your network;
|
|
129
|
+
- requires the random token printed at startup; the token is swapped for an `HttpOnly`,
|
|
130
|
+
`SameSite=Strict` cookie scoped to that port;
|
|
131
|
+
- rejects any `Host` header other than `127.0.0.1:<port>`/`localhost:<port>`, which blocks
|
|
132
|
+
DNS rebinding;
|
|
133
|
+
- rejects state-changing requests without a same-origin `Origin` header and htmx's request
|
|
134
|
+
header, so other sites can't make it send requests;
|
|
135
|
+
- sends a strict Content-Security-Policy (no inline or third-party scripts), shows response
|
|
136
|
+
bodies only as escaped text, and marks every response `Cache-Control: no-store`.
|
|
137
|
+
|
|
138
|
+
Found a hole? Please report it privately; see [SECURITY.md](SECURITY.md).
|
|
139
|
+
|
|
140
|
+
## Requirements
|
|
141
|
+
|
|
142
|
+
Python 3.11+ (`uvx` will fetch one for you) and a web browser. Git is optional.
|
|
143
|
+
|
|
144
|
+
## Roadmap
|
|
145
|
+
|
|
146
|
+
- Import from Postman collections, curl commands and HAR files
|
|
147
|
+
- A native window (`pip install librepost-app[desktop]`)
|
|
148
|
+
- Git status and commit from the UI
|
|
149
|
+
- Client certificates (mTLS), proxy settings, request history and response diffs
|
|
150
|
+
- More secret providers: 1Password CLI, HashiCorp Vault, `pass`
|
|
151
|
+
|
|
152
|
+
## Contributing
|
|
153
|
+
|
|
154
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
[MIT](LICENSE). The bundled [htmx](https://htmx.org) is under the
|
|
159
|
+
[Zero-Clause BSD](src/librepost/static/vendor/htmx-LICENSE.txt) licence.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "librepost-app"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A free, local-first API client. Requests live as plain .http files in your git repo; secrets stay in your keychain."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = [
|
|
8
|
+
"LICENSE",
|
|
9
|
+
"src/librepost/static/vendor/htmx-LICENSE.txt",
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
keywords = [
|
|
13
|
+
"api",
|
|
14
|
+
"http",
|
|
15
|
+
"rest",
|
|
16
|
+
"client",
|
|
17
|
+
"postman-alternative",
|
|
18
|
+
"http-file",
|
|
19
|
+
"git",
|
|
20
|
+
"local-first",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 3 - Alpha",
|
|
24
|
+
"Environment :: Console",
|
|
25
|
+
"Environment :: Web Environment",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13",
|
|
31
|
+
"Programming Language :: Python :: 3.14",
|
|
32
|
+
"Operating System :: OS Independent",
|
|
33
|
+
"Typing :: Typed",
|
|
34
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
35
|
+
"Topic :: Software Development :: Testing",
|
|
36
|
+
]
|
|
37
|
+
dependencies = [
|
|
38
|
+
"httpx>=0.27",
|
|
39
|
+
"jinja2>=3.1",
|
|
40
|
+
"keyring>=25.0",
|
|
41
|
+
"python-multipart>=0.0.9",
|
|
42
|
+
"rich>=13.7",
|
|
43
|
+
"starlette>=0.40",
|
|
44
|
+
"typer>=0.12",
|
|
45
|
+
"uvicorn>=0.30",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[[project.authors]]
|
|
49
|
+
name = "Ag3nt Sc4rn"
|
|
50
|
+
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/ag3ntsc4rn/librepost"
|
|
53
|
+
Issues = "https://github.com/ag3ntsc4rn/librepost/issues"
|
|
54
|
+
Changelog = "https://github.com/ag3ntsc4rn/librepost/blob/main/CHANGELOG.md"
|
|
55
|
+
|
|
56
|
+
[project.scripts]
|
|
57
|
+
librepost = "librepost.cli:app"
|
|
58
|
+
librepost-app = "librepost.cli:app"
|
|
59
|
+
|
|
60
|
+
[dependency-groups]
|
|
61
|
+
dev = [
|
|
62
|
+
"pytest>=8.0",
|
|
63
|
+
"mypy>=1.11",
|
|
64
|
+
"pre-commit>=3.7",
|
|
65
|
+
"ruff>=0.6",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[build-system]
|
|
69
|
+
requires = ["uv_build>=0.8,<0.14"]
|
|
70
|
+
build-backend = "uv_build"
|
|
71
|
+
|
|
72
|
+
[tool.uv.build-backend]
|
|
73
|
+
module-name = "librepost"
|
|
74
|
+
|
|
75
|
+
[tool.ruff]
|
|
76
|
+
line-length = 100
|
|
77
|
+
target-version = "py311"
|
|
78
|
+
|
|
79
|
+
[tool.ruff.lint]
|
|
80
|
+
select = [
|
|
81
|
+
"E",
|
|
82
|
+
"F",
|
|
83
|
+
"I",
|
|
84
|
+
"B",
|
|
85
|
+
"UP",
|
|
86
|
+
"SIM",
|
|
87
|
+
]
|
|
88
|
+
ignore = ["E501"]
|
|
89
|
+
|
|
90
|
+
[tool.mypy]
|
|
91
|
+
strict = true
|
|
92
|
+
files = ["src"]
|
|
93
|
+
|
|
94
|
+
[[tool.mypy.overrides]]
|
|
95
|
+
module = [
|
|
96
|
+
"keyring",
|
|
97
|
+
"keyring.*",
|
|
98
|
+
]
|
|
99
|
+
ignore_missing_imports = true
|
|
100
|
+
|
|
101
|
+
[tool.pytest.ini_options]
|
|
102
|
+
testpaths = ["tests"]
|
|
103
|
+
filterwarnings = ["ignore:Using `httpx` with `starlette.testclient`"]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "librepost-app"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A free, local-first API client. Requests live as plain .http files in your git repo; secrets stay in your keychain."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE", "src/librepost/static/vendor/htmx-LICENSE.txt"]
|
|
8
|
+
authors = [{ name = "Ag3nt Sc4rn" }]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
keywords = ["api", "http", "rest", "client", "postman-alternative", "http-file", "git", "local-first"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Environment :: Web Environment",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Typing :: Typed",
|
|
23
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
24
|
+
"Topic :: Software Development :: Testing",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"httpx>=0.27",
|
|
28
|
+
"jinja2>=3.1",
|
|
29
|
+
"keyring>=25.0",
|
|
30
|
+
"python-multipart>=0.0.9",
|
|
31
|
+
"rich>=13.7",
|
|
32
|
+
"starlette>=0.40",
|
|
33
|
+
"typer>=0.12",
|
|
34
|
+
"uvicorn>=0.30",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/ag3ntsc4rn/librepost"
|
|
39
|
+
Issues = "https://github.com/ag3ntsc4rn/librepost/issues"
|
|
40
|
+
Changelog = "https://github.com/ag3ntsc4rn/librepost/blob/main/CHANGELOG.md"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
librepost = "librepost.cli:app"
|
|
44
|
+
# Same command under the PyPI name, so `uvx librepost-app ui` works.
|
|
45
|
+
librepost-app = "librepost.cli:app"
|
|
46
|
+
|
|
47
|
+
[dependency-groups]
|
|
48
|
+
dev = [
|
|
49
|
+
"pytest>=8.0",
|
|
50
|
+
"mypy>=1.11",
|
|
51
|
+
"pre-commit>=3.7",
|
|
52
|
+
"ruff>=0.6",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[build-system]
|
|
56
|
+
requires = ["uv_build>=0.8,<0.14"]
|
|
57
|
+
build-backend = "uv_build"
|
|
58
|
+
|
|
59
|
+
[tool.uv.build-backend]
|
|
60
|
+
# The PyPI name is librepost-app; the importable package is librepost.
|
|
61
|
+
module-name = "librepost"
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 100
|
|
65
|
+
target-version = "py311"
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = ["E", "F", "I", "B", "UP", "SIM"]
|
|
69
|
+
# The formatter keeps code within line-length; long string literals are left alone.
|
|
70
|
+
ignore = ["E501"]
|
|
71
|
+
|
|
72
|
+
[tool.mypy]
|
|
73
|
+
strict = true
|
|
74
|
+
files = ["src"]
|
|
75
|
+
|
|
76
|
+
[[tool.mypy.overrides]]
|
|
77
|
+
module = ["keyring", "keyring.*"]
|
|
78
|
+
ignore_missing_imports = true
|
|
79
|
+
|
|
80
|
+
[tool.pytest.ini_options]
|
|
81
|
+
testpaths = ["tests"]
|
|
82
|
+
# Starlette suggests httpx2 for its TestClient; httpx is what librepost ships with.
|
|
83
|
+
filterwarnings = ["ignore:Using `httpx` with `starlette.testclient`"]
|