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.
Files changed (29) hide show
  1. librepost_app-0.1.0/LICENSE +21 -0
  2. librepost_app-0.1.0/PKG-INFO +195 -0
  3. librepost_app-0.1.0/README.md +159 -0
  4. librepost_app-0.1.0/pyproject.toml +103 -0
  5. librepost_app-0.1.0/pyproject.toml.orig +83 -0
  6. librepost_app-0.1.0/src/librepost/__init__.py +3 -0
  7. librepost_app-0.1.0/src/librepost/__main__.py +3 -0
  8. librepost_app-0.1.0/src/librepost/cli.py +301 -0
  9. librepost_app-0.1.0/src/librepost/environments.py +71 -0
  10. librepost_app-0.1.0/src/librepost/httpfile.py +205 -0
  11. librepost_app-0.1.0/src/librepost/leakcheck.py +182 -0
  12. librepost_app-0.1.0/src/librepost/py.typed +0 -0
  13. librepost_app-0.1.0/src/librepost/runner.py +118 -0
  14. librepost_app-0.1.0/src/librepost/secretstore.py +73 -0
  15. librepost_app-0.1.0/src/librepost/server.py +312 -0
  16. librepost_app-0.1.0/src/librepost/static/app.css +311 -0
  17. librepost_app-0.1.0/src/librepost/static/app.js +62 -0
  18. librepost_app-0.1.0/src/librepost/static/icon.svg +1 -0
  19. librepost_app-0.1.0/src/librepost/static/vendor/htmx-2.0.11.min.js +1 -0
  20. librepost_app-0.1.0/src/librepost/static/vendor/htmx-LICENSE.txt +13 -0
  21. librepost_app-0.1.0/src/librepost/template.py +95 -0
  22. librepost_app-0.1.0/src/librepost/templates/editor.html +38 -0
  23. librepost_app-0.1.0/src/librepost/templates/empty.html +6 -0
  24. librepost_app-0.1.0/src/librepost/templates/error.html +1 -0
  25. librepost_app-0.1.0/src/librepost/templates/index.html +49 -0
  26. librepost_app-0.1.0/src/librepost/templates/response.html +41 -0
  27. librepost_app-0.1.0/src/librepost/templates/status.html +1 -0
  28. librepost_app-0.1.0/src/librepost/templates/tree.html +20 -0
  29. 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
+ [![CI](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml/badge.svg)](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml)
40
+ [![PyPI](https://img.shields.io/pypi/v/librepost-app?cacheSeconds=3600)](https://pypi.org/project/librepost-app/)
41
+ [![Python](https://img.shields.io/pypi/pyversions/librepost-app?cacheSeconds=3600)](https://pypi.org/project/librepost-app/)
42
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](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
+ [![CI](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml/badge.svg)](https://github.com/ag3ntsc4rn/librepost/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/librepost-app?cacheSeconds=3600)](https://pypi.org/project/librepost-app/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/librepost-app?cacheSeconds=3600)](https://pypi.org/project/librepost-app/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](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`"]
@@ -0,0 +1,3 @@
1
+ """A free, local-first API client."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from .cli import app
2
+
3
+ app(prog_name="librepost")