blog-cli 0.2.2__tar.gz → 0.3.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.
@@ -0,0 +1,262 @@
1
+ Metadata-Version: 2.4
2
+ Name: blog-cli
3
+ Version: 0.3.0
4
+ Summary: Agent-friendly CLI for managing a blog. Create drafts, upload media, generate time-limited preview links.
5
+ Author: tanaka-mambinge
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/tanaka-mambinge/personal-cli
8
+ Project-URL: Issues, https://github.com/tanaka-mambinge/personal-cli/issues
9
+ Keywords: blog,cli,agent,markdown,writing
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Internet :: WWW/HTTP
14
+ Requires-Python: >=3.13
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: httpx>=0.28
17
+ Requires-Dist: keyring>=25
18
+ Requires-Dist: typer>=0.16
19
+ Provides-Extra: dev
20
+ Requires-Dist: asgi-lifespan>=2.1; extra == "dev"
21
+ Requires-Dist: fastapi>=0.115; extra == "dev"
22
+ Requires-Dist: motor>=3.7; extra == "dev"
23
+ Requires-Dist: pytest>=8.3; extra == "dev"
24
+ Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
25
+ Requires-Dist: pydantic>=2.10; extra == "dev"
26
+ Requires-Dist: pydantic-settings>=2.6; extra == "dev"
27
+ Requires-Dist: pymongo>=4.9; extra == "dev"
28
+ Requires-Dist: python-multipart>=0.0.20; extra == "dev"
29
+ Requires-Dist: uvicorn>=0.49; extra == "dev"
30
+
31
+ # blog-cli
32
+
33
+ Agent-friendly CLI for managing a personal blog: create drafts, upload media, generate preview links, publish articles, and manage project tags.
34
+
35
+ ## Install
36
+
37
+ From PyPI:
38
+
39
+ ```bash
40
+ pip install blog-cli
41
+ ```
42
+
43
+ Or install it as an isolated command-line tool:
44
+
45
+ ```bash
46
+ pipx install blog-cli
47
+ uv tool install blog-cli
48
+ ```
49
+
50
+ For development:
51
+
52
+ ```bash
53
+ git clone https://github.com/tanaka-mambinge/personal-cli
54
+ cd personal-cli
55
+ uv sync --extra dev
56
+ ```
57
+
58
+ ## Configure
59
+
60
+ The CLI requires the API URL and API key. The site URL is required for preview links.
61
+
62
+ ```bash
63
+ export PERSONAL_SERVER_URL="https://api.example.com"
64
+ export PERSONAL_API_KEY="your-api-key"
65
+ export PERSONAL_SITE_URL="https://example.com"
66
+ ```
67
+
68
+ For local development, put the same variables in a `.env` file in the current directory. Do not commit that file.
69
+
70
+ Production installations use the same environment variables. For example:
71
+
72
+ ```bash
73
+ PERSONAL_SERVER_URL="https://api.example.com" \
74
+ PERSONAL_API_KEY="your-production-api-key" \
75
+ PERSONAL_SITE_URL="https://example.com" \
76
+ blog-cli article list --type blog
77
+ ```
78
+
79
+ All commands support `--json` for machine-readable output and `--server-url` to override the configured API URL for one command. Commands also support `--insecure` to skip TLS certificate verification when needed for local development.
80
+
81
+ Check the installed version:
82
+
83
+ ```bash
84
+ blog-cli version
85
+ ```
86
+
87
+ ## Articles
88
+
89
+ ### Create a blog post
90
+
91
+ Blog posts are drafts by default:
92
+
93
+ ```bash
94
+ blog-cli article blog create \
95
+ --title "My Post" \
96
+ --description "A short summary" \
97
+ --markdown "# My Post\n\nHello."
98
+ ```
99
+
100
+ Use a Markdown file instead:
101
+
102
+ ```bash
103
+ blog-cli article blog create \
104
+ --title "My Post" \
105
+ --description "A short summary" \
106
+ --markdown-file post.md
107
+ ```
108
+
109
+ ### Create a project
110
+
111
+ ```bash
112
+ blog-cli article project create \
113
+ --title "My Project" \
114
+ --description "A short summary" \
115
+ --tag python \
116
+ --tag agents \
117
+ --markdown-file project.md
118
+ ```
119
+
120
+ Projects can also use `--pinned` and `--sort-order`.
121
+
122
+ ### List and show articles
123
+
124
+ ```bash
125
+ # List all articles
126
+ blog-cli article list
127
+
128
+ # List published blog posts
129
+ blog-cli article list --type blog --status published
130
+
131
+ # List projects
132
+ blog-cli article list --type project
133
+
134
+ # Show one article
135
+ blog-cli article show my-post
136
+ ```
137
+
138
+ ### Update an article
139
+
140
+ ```bash
141
+ blog-cli article update my-post --title "A Better Title"
142
+ blog-cli article update my-post --description "An updated summary"
143
+ blog-cli article update my-post --markdown-file updated-post.md
144
+ blog-cli article update my-post --cover-image hero-image
145
+ blog-cli article update my-post --clear-cover-image
146
+ ```
147
+
148
+ The update command also accepts `--type`, `--status`, `--tag`, `--pinned`, `--not-pinned`, and `--sort-order`.
149
+
150
+ ### Preview and publish
151
+
152
+ Generate a time-limited preview link:
153
+
154
+ ```bash
155
+ blog-cli article preview my-post
156
+ blog-cli article preview my-post --ttl-hours 4
157
+ ```
158
+
159
+ Override the configured site URL for a preview:
160
+
161
+ ```bash
162
+ blog-cli article preview my-post --site-url https://preview.example.com
163
+ ```
164
+
165
+ Revoke an existing preview link:
166
+
167
+ ```bash
168
+ blog-cli article revoke-preview my-post
169
+ ```
170
+
171
+ Publish an article explicitly:
172
+
173
+ ```bash
174
+ blog-cli article publish my-post --published-by agent
175
+ ```
176
+
177
+ Archive or restore an article:
178
+
179
+ ```bash
180
+ blog-cli article delete my-post
181
+ blog-cli article unarchive my-post
182
+ ```
183
+
184
+ ### Project tags
185
+
186
+ ```bash
187
+ # List tags on a project
188
+ blog-cli article tag-list my-project
189
+
190
+ # Add tags
191
+ blog-cli article tag-add my-project --tag python --tag agents
192
+
193
+ # Remove a tag
194
+ blog-cli article tag-remove my-project --tag agents
195
+ ```
196
+
197
+ ## Media
198
+
199
+ Upload media using a stable name, then reference that name from article Markdown:
200
+
201
+ ```bash
202
+ blog-cli media upload --name hero-image ./hero.jpg
203
+ ```
204
+
205
+ Replace an existing file without changing its name:
206
+
207
+ ```bash
208
+ blog-cli media update --name hero-image ./new-hero.jpg
209
+ ```
210
+
211
+ Soft-delete media:
212
+
213
+ ```bash
214
+ blog-cli media delete --name hero-image
215
+ ```
216
+
217
+ Markdown references use the media name:
218
+
219
+ ```markdown
220
+ ![Hero image](hero-image)
221
+
222
+ <video controls width="100%" src="demo-video"></video>
223
+ ```
224
+
225
+ The site resolves these names to their full media URLs.
226
+
227
+ ## Publishing new CLI versions
228
+
229
+ The repository includes a GitHub Actions workflow at `.github/workflows/publish.yml`. It runs when you push a version tag matching `v*.*.*` and will:
230
+
231
+ 1. Install dependencies with uv.
232
+ 2. Run the test suite.
233
+ 3. Build the wheel and source distribution with `uv build --no-sources`.
234
+ 4. Publish both distributions to PyPI with `uv publish`.
235
+
236
+ After configuring PyPI Trusted Publishing for the GitHub Actions workflow, release a new version with:
237
+
238
+ ```bash
239
+ uv version --bump patch
240
+ git add pyproject.toml uv.lock
241
+ git commit -m "Release blog-cli"
242
+ git tag v0.2.4
243
+ git push origin main --tags
244
+ ```
245
+
246
+ Use the version from `pyproject.toml` when creating the tag.
247
+
248
+ ## Testing
249
+
250
+ ```bash
251
+ uv run pytest -v
252
+ ```
253
+
254
+ The CLI tests use an in-memory fake API client, so they run without MongoDB or the personal server. The CLI architecture is:
255
+
256
+ ```text
257
+ blog-cli (httpx) → FastAPI server → MongoDB/GridFS
258
+ ```
259
+
260
+ ## License
261
+
262
+ MIT
@@ -0,0 +1,232 @@
1
+ # blog-cli
2
+
3
+ Agent-friendly CLI for managing a personal blog: create drafts, upload media, generate preview links, publish articles, and manage project tags.
4
+
5
+ ## Install
6
+
7
+ From PyPI:
8
+
9
+ ```bash
10
+ pip install blog-cli
11
+ ```
12
+
13
+ Or install it as an isolated command-line tool:
14
+
15
+ ```bash
16
+ pipx install blog-cli
17
+ uv tool install blog-cli
18
+ ```
19
+
20
+ For development:
21
+
22
+ ```bash
23
+ git clone https://github.com/tanaka-mambinge/personal-cli
24
+ cd personal-cli
25
+ uv sync --extra dev
26
+ ```
27
+
28
+ ## Configure
29
+
30
+ The CLI requires the API URL and API key. The site URL is required for preview links.
31
+
32
+ ```bash
33
+ export PERSONAL_SERVER_URL="https://api.example.com"
34
+ export PERSONAL_API_KEY="your-api-key"
35
+ export PERSONAL_SITE_URL="https://example.com"
36
+ ```
37
+
38
+ For local development, put the same variables in a `.env` file in the current directory. Do not commit that file.
39
+
40
+ Production installations use the same environment variables. For example:
41
+
42
+ ```bash
43
+ PERSONAL_SERVER_URL="https://api.example.com" \
44
+ PERSONAL_API_KEY="your-production-api-key" \
45
+ PERSONAL_SITE_URL="https://example.com" \
46
+ blog-cli article list --type blog
47
+ ```
48
+
49
+ All commands support `--json` for machine-readable output and `--server-url` to override the configured API URL for one command. Commands also support `--insecure` to skip TLS certificate verification when needed for local development.
50
+
51
+ Check the installed version:
52
+
53
+ ```bash
54
+ blog-cli version
55
+ ```
56
+
57
+ ## Articles
58
+
59
+ ### Create a blog post
60
+
61
+ Blog posts are drafts by default:
62
+
63
+ ```bash
64
+ blog-cli article blog create \
65
+ --title "My Post" \
66
+ --description "A short summary" \
67
+ --markdown "# My Post\n\nHello."
68
+ ```
69
+
70
+ Use a Markdown file instead:
71
+
72
+ ```bash
73
+ blog-cli article blog create \
74
+ --title "My Post" \
75
+ --description "A short summary" \
76
+ --markdown-file post.md
77
+ ```
78
+
79
+ ### Create a project
80
+
81
+ ```bash
82
+ blog-cli article project create \
83
+ --title "My Project" \
84
+ --description "A short summary" \
85
+ --tag python \
86
+ --tag agents \
87
+ --markdown-file project.md
88
+ ```
89
+
90
+ Projects can also use `--pinned` and `--sort-order`.
91
+
92
+ ### List and show articles
93
+
94
+ ```bash
95
+ # List all articles
96
+ blog-cli article list
97
+
98
+ # List published blog posts
99
+ blog-cli article list --type blog --status published
100
+
101
+ # List projects
102
+ blog-cli article list --type project
103
+
104
+ # Show one article
105
+ blog-cli article show my-post
106
+ ```
107
+
108
+ ### Update an article
109
+
110
+ ```bash
111
+ blog-cli article update my-post --title "A Better Title"
112
+ blog-cli article update my-post --description "An updated summary"
113
+ blog-cli article update my-post --markdown-file updated-post.md
114
+ blog-cli article update my-post --cover-image hero-image
115
+ blog-cli article update my-post --clear-cover-image
116
+ ```
117
+
118
+ The update command also accepts `--type`, `--status`, `--tag`, `--pinned`, `--not-pinned`, and `--sort-order`.
119
+
120
+ ### Preview and publish
121
+
122
+ Generate a time-limited preview link:
123
+
124
+ ```bash
125
+ blog-cli article preview my-post
126
+ blog-cli article preview my-post --ttl-hours 4
127
+ ```
128
+
129
+ Override the configured site URL for a preview:
130
+
131
+ ```bash
132
+ blog-cli article preview my-post --site-url https://preview.example.com
133
+ ```
134
+
135
+ Revoke an existing preview link:
136
+
137
+ ```bash
138
+ blog-cli article revoke-preview my-post
139
+ ```
140
+
141
+ Publish an article explicitly:
142
+
143
+ ```bash
144
+ blog-cli article publish my-post --published-by agent
145
+ ```
146
+
147
+ Archive or restore an article:
148
+
149
+ ```bash
150
+ blog-cli article delete my-post
151
+ blog-cli article unarchive my-post
152
+ ```
153
+
154
+ ### Project tags
155
+
156
+ ```bash
157
+ # List tags on a project
158
+ blog-cli article tag-list my-project
159
+
160
+ # Add tags
161
+ blog-cli article tag-add my-project --tag python --tag agents
162
+
163
+ # Remove a tag
164
+ blog-cli article tag-remove my-project --tag agents
165
+ ```
166
+
167
+ ## Media
168
+
169
+ Upload media using a stable name, then reference that name from article Markdown:
170
+
171
+ ```bash
172
+ blog-cli media upload --name hero-image ./hero.jpg
173
+ ```
174
+
175
+ Replace an existing file without changing its name:
176
+
177
+ ```bash
178
+ blog-cli media update --name hero-image ./new-hero.jpg
179
+ ```
180
+
181
+ Soft-delete media:
182
+
183
+ ```bash
184
+ blog-cli media delete --name hero-image
185
+ ```
186
+
187
+ Markdown references use the media name:
188
+
189
+ ```markdown
190
+ ![Hero image](hero-image)
191
+
192
+ <video controls width="100%" src="demo-video"></video>
193
+ ```
194
+
195
+ The site resolves these names to their full media URLs.
196
+
197
+ ## Publishing new CLI versions
198
+
199
+ The repository includes a GitHub Actions workflow at `.github/workflows/publish.yml`. It runs when you push a version tag matching `v*.*.*` and will:
200
+
201
+ 1. Install dependencies with uv.
202
+ 2. Run the test suite.
203
+ 3. Build the wheel and source distribution with `uv build --no-sources`.
204
+ 4. Publish both distributions to PyPI with `uv publish`.
205
+
206
+ After configuring PyPI Trusted Publishing for the GitHub Actions workflow, release a new version with:
207
+
208
+ ```bash
209
+ uv version --bump patch
210
+ git add pyproject.toml uv.lock
211
+ git commit -m "Release blog-cli"
212
+ git tag v0.2.4
213
+ git push origin main --tags
214
+ ```
215
+
216
+ Use the version from `pyproject.toml` when creating the tag.
217
+
218
+ ## Testing
219
+
220
+ ```bash
221
+ uv run pytest -v
222
+ ```
223
+
224
+ The CLI tests use an in-memory fake API client, so they run without MongoDB or the personal server. The CLI architecture is:
225
+
226
+ ```text
227
+ blog-cli (httpx) → FastAPI server → MongoDB/GridFS
228
+ ```
229
+
230
+ ## License
231
+
232
+ MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "blog-cli"
7
- version = "0.2.2"
7
+ version = "0.3.0"
8
8
  description = "Agent-friendly CLI for managing a blog. Create drafts, upload media, generate time-limited preview links."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -19,6 +19,7 @@ classifiers = [
19
19
  ]
20
20
  dependencies = [
21
21
  "httpx>=0.28",
22
+ "keyring>=25",
22
23
  "typer>=0.16",
23
24
  ]
24
25