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