python-substack 0.4.0__tar.gz → 0.6.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-substack
3
- Version: 0.4.0
3
+ Version: 0.6.0
4
4
  Summary: Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -23,7 +23,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Provides-Extra: mcp
24
24
  Requires-Dist: PyYAML (>=6.0,<7.0)
25
25
  Requires-Dist: fastmcp (>=3.1.1,<4.0.0) ; extra == "mcp"
26
- Requires-Dist: markdown-it-py (>=3.0,<4.0)
26
+ Requires-Dist: markdown-it-py (>=3,<5)
27
27
  Requires-Dist: mdit-py-plugins (>=0.5,<0.7)
28
28
  Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
29
29
  Requires-Dist: requests (>=2.32.0,<3.0.0)
@@ -93,6 +93,7 @@ Substack result:
93
93
  - Upload local images referenced by Markdown.
94
94
  - Set audience, comment permissions, SEO metadata, slug, sections, and tags.
95
95
  - List and inspect publications and drafts.
96
+ - Export drafts to loss-aware Markdown backups without server writes.
96
97
  - Schedule, unschedule, publish, and delete drafts with explicit safeguards.
97
98
  - Use stable JSON envelopes in scripts and automation.
98
99
  - Authenticate with browser cookies or email and password.
@@ -143,6 +144,7 @@ Inspect publications and drafts:
143
144
  substack publications list
144
145
  substack drafts list --limit 10
145
146
  substack drafts get 12345
147
+ substack drafts export 12345 --output backup.md
146
148
  substack --publication-url https://example.substack.com drafts list
147
149
  ```
148
150
 
@@ -207,6 +209,14 @@ print(result["draft"]["id"])
207
209
  `create_draft_from_markdown` creates a draft by default. It publishes only when
208
210
  `publish=True` is passed.
209
211
 
212
+ Back up an existing draft without modifying it:
213
+
214
+ ```python
215
+ backup = api.export_draft_to_markdown(12345)
216
+ print(backup["markdown"])
217
+ print(backup["unsupported_nodes"])
218
+ ```
219
+
210
220
  For direct ProseMirror node construction, see the
211
221
  [low-level Python API](docs/low-level-api.md). YAML workflows are documented in
212
222
  [YAML drafts](docs/yaml.md).
@@ -57,6 +57,7 @@ Substack result:
57
57
  - Upload local images referenced by Markdown.
58
58
  - Set audience, comment permissions, SEO metadata, slug, sections, and tags.
59
59
  - List and inspect publications and drafts.
60
+ - Export drafts to loss-aware Markdown backups without server writes.
60
61
  - Schedule, unschedule, publish, and delete drafts with explicit safeguards.
61
62
  - Use stable JSON envelopes in scripts and automation.
62
63
  - Authenticate with browser cookies or email and password.
@@ -107,6 +108,7 @@ Inspect publications and drafts:
107
108
  substack publications list
108
109
  substack drafts list --limit 10
109
110
  substack drafts get 12345
111
+ substack drafts export 12345 --output backup.md
110
112
  substack --publication-url https://example.substack.com drafts list
111
113
  ```
112
114
 
@@ -171,6 +173,14 @@ print(result["draft"]["id"])
171
173
  `create_draft_from_markdown` creates a draft by default. It publishes only when
172
174
  `publish=True` is passed.
173
175
 
176
+ Back up an existing draft without modifying it:
177
+
178
+ ```python
179
+ backup = api.export_draft_to_markdown(12345)
180
+ print(backup["markdown"])
181
+ print(backup["unsupported_nodes"])
182
+ ```
183
+
174
184
  For direct ProseMirror node construction, see the
175
185
  [low-level Python API](docs/low-level-api.md). YAML workflows are documented in
176
186
  [YAML drafts](docs/yaml.md).
@@ -1,67 +1,67 @@
1
- [tool.poetry]
2
- name = "python-substack"
3
- version = "0.4.0"
4
- description = "Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP."
5
- authors = ["Paolo Mazza <mazzapaolo2019@gmail.com>"]
6
- license = "MIT"
7
- packages = [
8
- { include = "substack" },
9
- { include = "substack_mcp" }
10
- ]
11
-
12
- readme = "README.md"
13
-
14
- repository = "https://github.com/ma2za/python-substack"
15
- homepage = "https://github.com/ma2za/python-substack"
16
-
17
- keywords = ["substack", "substack-api", "cli", "newsletter", "publishing", "automation", "mcp"]
18
- classifiers = [
19
- "Development Status :: 4 - Beta",
20
- "Intended Audience :: Developers",
21
- "Programming Language :: Python :: 3",
22
- "Programming Language :: Python :: 3.10",
23
- "Programming Language :: Python :: 3.11",
24
- "Programming Language :: Python :: 3.12",
25
- "Programming Language :: Python :: 3.13",
26
- "Topic :: Communications :: Email",
27
- "Topic :: Internet :: WWW/HTTP",
28
- "Topic :: Software Development :: Libraries :: Python Modules"
29
- ]
30
-
31
- [tool.poetry.urls]
32
- "Documentation" = "https://ma2za.github.io/python-substack/"
33
- "Changelog" = "https://github.com/ma2za/python-substack/blob/main/CHANGELOG.md"
34
- "Issues" = "https://github.com/ma2za/python-substack/issues"
35
-
36
- [tool.poetry.dependencies]
37
- python = "<4.0,>=3.10"
38
-
39
- requests = "^2.32.0"
40
- python-dotenv = "^1.2.1"
41
- PyYAML = "^6.0"
42
- markdown-it-py = "^3.0"
43
- mdit-py-plugins = ">=0.5,<0.7"
44
- fastmcp = { version = "^3.1.1", optional = true }
45
-
46
- [tool.poetry.extras]
47
- mcp = ["fastmcp"]
48
-
49
- [tool.poetry.group.dev.dependencies]
50
- pytest = "^9.1.1"
51
- pre-commit = "^4.6.1"
52
-
53
- [tool.pytest.ini_options]
54
- markers = [
55
- "live: opt-in tests that call the live Substack service",
56
- ]
57
-
58
- [tool.poetry.scripts]
59
- substack = "substack.cli:main"
60
- substack-auth-check = "substack.cli:auth_check"
61
- substack-publish-markdown = "substack.cli:publish_markdown"
62
- substack-publish-yaml = "substack.cli:publish_yaml"
63
- substack-mcp = "substack_mcp.mcp_server:main"
64
-
65
- [build-system]
66
- requires = ["poetry-core>=1.0.0"]
67
- build-backend = "poetry.core.masonry.api"
1
+ [tool.poetry]
2
+ name = "python-substack"
3
+ version = "0.6.0"
4
+ description = "Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP."
5
+ authors = ["Paolo Mazza <mazzapaolo2019@gmail.com>"]
6
+ license = "MIT"
7
+ packages = [
8
+ { include = "substack" },
9
+ { include = "substack_mcp" }
10
+ ]
11
+
12
+ readme = "README.md"
13
+
14
+ repository = "https://github.com/ma2za/python-substack"
15
+ homepage = "https://github.com/ma2za/python-substack"
16
+
17
+ keywords = ["substack", "substack-api", "cli", "newsletter", "publishing", "automation", "mcp"]
18
+ classifiers = [
19
+ "Development Status :: 4 - Beta",
20
+ "Intended Audience :: Developers",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Communications :: Email",
27
+ "Topic :: Internet :: WWW/HTTP",
28
+ "Topic :: Software Development :: Libraries :: Python Modules"
29
+ ]
30
+
31
+ [tool.poetry.urls]
32
+ "Documentation" = "https://ma2za.github.io/python-substack/"
33
+ "Changelog" = "https://github.com/ma2za/python-substack/blob/main/CHANGELOG.md"
34
+ "Issues" = "https://github.com/ma2za/python-substack/issues"
35
+
36
+ [tool.poetry.dependencies]
37
+ python = "<4.0,>=3.10"
38
+
39
+ requests = "^2.32.0"
40
+ python-dotenv = "^1.2.1"
41
+ PyYAML = "^6.0"
42
+ markdown-it-py = ">=3,<5"
43
+ mdit-py-plugins = ">=0.5,<0.7"
44
+ fastmcp = { version = "^3.1.1", optional = true }
45
+
46
+ [tool.poetry.extras]
47
+ mcp = ["fastmcp"]
48
+
49
+ [tool.poetry.group.dev.dependencies]
50
+ pytest = "^9.1.1"
51
+ pre-commit = "^4.6.1"
52
+
53
+ [tool.pytest.ini_options]
54
+ markers = [
55
+ "live: opt-in tests that call the live Substack service",
56
+ ]
57
+
58
+ [tool.poetry.scripts]
59
+ substack = "substack.cli:main"
60
+ substack-auth-check = "substack.cli:auth_check"
61
+ substack-publish-markdown = "substack.cli:publish_markdown"
62
+ substack-publish-yaml = "substack.cli:publish_yaml"
63
+ substack-mcp = "substack_mcp.mcp_server:main"
64
+
65
+ [build-system]
66
+ requires = ["poetry-core>=1.0.0"]
67
+ build-backend = "poetry.core.masonry.api"
@@ -1,13 +1,13 @@
1
- """A library that provides a Python interface to the Substack API."""
2
-
3
- __author__ = "Paolo Mazza"
4
- __email__ = "mazzapaolo2019@gmail.com"
5
- __license__ = "MIT License"
6
- __version__ = "0.4.0"
7
- __url__ = "https://github.com/ma2za/python-substack"
8
- __download_url__ = "https://pypi.python.org/pypi/python-substack"
9
- __description__ = (
10
- "Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP."
11
- )
12
-
13
- from .api import Api
1
+ """A library that provides a Python interface to the Substack API."""
2
+
3
+ __author__ = "Paolo Mazza"
4
+ __email__ = "mazzapaolo2019@gmail.com"
5
+ __license__ = "MIT License"
6
+ __version__ = "0.6.0"
7
+ __url__ = "https://github.com/ma2za/python-substack"
8
+ __download_url__ = "https://pypi.python.org/pypi/python-substack"
9
+ __description__ = (
10
+ "Write and safely manage Substack drafts from Markdown with Python, CLI, and MCP."
11
+ )
12
+
13
+ from .api import Api