Python client library for markdown.new URL-to-Markdown conversion
Project description
markdown-new
Python client for markdown.new, a Cloudflare-backed service that converts web URLs into Markdown.
Table of contents
- What the project does
- Why this project is useful
- Get started
- Configuration and usage patterns
- Response and errors
- Testing
- Project help
- Maintainers and contributing
What the project does
markdown-new is a lightweight, production-oriented Python client for the public markdown.new conversion endpoint. It handles:
- URL normalization for request-path-based conversions
- Synchronous and asynchronous HTTP client workflows
- Typed request/response handling
- Consistent error mapping for service failures
- Optional authentication header customization
- Lightweight markdown token metadata extraction when present
Why this project is useful
- Fast integration: one method call to convert a URL into Markdown.
- Reliable transport options: supports both blocking and
asynciousage. - Built-in validation: validates URL inputs (scheme + host) before the network call.
- Predictable error handling: clear exception classes for URL, authentication, rate limit, conversion, and transport failures.
- Type-aware:
py.typedmarker and explicit response model for IDE-friendly development. - Practical ergonomics: context managers and batch helpers are included for both client types.
Get started
Installation
Install from PyPI:
pip install markdown-new
Install with development dependencies:
pip install -e ".[dev]"
Quick start (sync)
from markdown_new import MarkdownNewClient
with MarkdownNewClient() as client:
result = client.convert("https://example.com")
print(result.markdown)
print(result.requested_url)
print(result.status_code)
Quick start (async)
import asyncio
from markdown_new import AsyncMarkdownNewClient
async def main() -> None:
async with AsyncMarkdownNewClient() as client:
result = await client.convert("https://example.com")
print(result.markdown)
print(result.requested_url)
asyncio.run(main())
Batch conversion
from markdown_new import MarkdownNewClient, AsyncMarkdownNewClient
urls = [
"https://example.com",
"https://blog.cloudflare.com/markdown-for-agents/",
]
with MarkdownNewClient() as client:
sync_results = client.convert_many(urls)
for item in sync_results:
print(item.requested_url, "->", len(item.markdown), "chars")
async def batch():
async with AsyncMarkdownNewClient() as client:
async_results = await client.convert_many(urls, concurrency=5)
for item in async_results:
print(item.requested_url, "tokens", item.markdown_tokens)
Configuration and usage patterns
markdown.new expects the URL as part of the request path, which means query strings and fragments are encoded by the client automatically.
You can customize request identity and authentication headers with optional client arguments:
from markdown_new import MarkdownNewClient
client = MarkdownNewClient(
api_key="YOUR_API_KEY",
api_key_header="Authorization",
api_key_prefix="Bearer",
user_agent="my-service/1.0",
headers={"Accept-Language": "en-US"},
)
HTTP behavior and URL handling
- Supported URL schemes:
httpandhttps - The client normalizes and URL-encodes target paths for you.
- Timeout is configurable per call or per client instance.
- Batch conversions use the input order.
Response and errors
Successful calls return MarkdownResponse:
markdown: converted Markdown payloadrequested_url: original URL passed by the callernormalized_url: encoded target URL sent to the servicestatus_code: HTTP status codecontent_type: normalized response media typemarkdown_tokens: optional token usage metadata from response headersheaders: response headers map
Errors are expressed through:
MarkdownNewInvalidURLErrorfor malformed inputMarkdownNewConversionErrorfor API-level conversion problemsMarkdownNewAuthenticationErrorfor 401/403 responsesMarkdownNewRateLimitErrorfor 429 responsesMarkdownNewHTTPErrorfor other unexpected non-success HTTP errorsMarkdownNewRequestErrorfor transport and unexpected client issues
Testing
Run unit tests:
pytest
Run live conversion tests against the network endpoint:
pytest -m integration
Recommended local quality gate:
ruff check .
ruff format .
black --check .
If you installed pre-commit, you can run:
pre-commit install
pre-commit run --all-files
Project help
- Homepage:
markdown.new - Issues: https://github.com/davelindo/markdown-new-python-client/issues
- Package metadata: https://github.com/davelindo/markdown-new-python-client
- Package docs: this README and inline docstrings in
markdown_new/
Maintainers and contributing
Maintainer:
- Dave Lindon —
dave@knowledge2.ai
Contributions are welcome:
- Open an issue for bugs, feature requests, or API questions.
- Open a pull request for improvements or fixes.
- See CONTRIBUTING.md for full contribution guidelines.
- Prefer
MarkdownNewClientandAsyncMarkdownNewClientchanges to include tests intests/.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markdown_new-0.0.3.tar.gz.
File metadata
- Download URL: markdown_new-0.0.3.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
632bb2ef6286d8ce053e65209da59f3507519f7aaaf01f32efcf48a93ce3546f
|
|
| MD5 |
7111594f6c752687a6b0b91a3f333f2c
|
|
| BLAKE2b-256 |
fe517126cd96618065d40dd410e42b52f67256056495dc7c477f3a336a717810
|
Provenance
The following attestation bundles were made for markdown_new-0.0.3.tar.gz:
Publisher:
publish.yml on davelindo/markdown-new-python-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
markdown_new-0.0.3.tar.gz -
Subject digest:
632bb2ef6286d8ce053e65209da59f3507519f7aaaf01f32efcf48a93ce3546f - Sigstore transparency entry: 948561918
- Sigstore integration time:
-
Permalink:
davelindo/markdown-new-python-client@19edd3518ce8827eda19d82a11504b8ae8800d76 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/davelindo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19edd3518ce8827eda19d82a11504b8ae8800d76 -
Trigger Event:
push
-
Statement type:
File details
Details for the file markdown_new-0.0.3-py3-none-any.whl.
File metadata
- Download URL: markdown_new-0.0.3-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a495e27161b4f9da77db5c1d28ebe7eb4f3fd6f27833194cdaeac9fd298ce3e0
|
|
| MD5 |
e710eb62acdebf8ae00615ffef4ccc3d
|
|
| BLAKE2b-256 |
1bc765bc8ecca26b5aca43bbd9312f6aae4beccae33079e8de62d42b9d27e7ce
|
Provenance
The following attestation bundles were made for markdown_new-0.0.3-py3-none-any.whl:
Publisher:
publish.yml on davelindo/markdown-new-python-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
markdown_new-0.0.3-py3-none-any.whl -
Subject digest:
a495e27161b4f9da77db5c1d28ebe7eb4f3fd6f27833194cdaeac9fd298ce3e0 - Sigstore transparency entry: 948561978
- Sigstore integration time:
-
Permalink:
davelindo/markdown-new-python-client@19edd3518ce8827eda19d82a11504b8ae8800d76 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/davelindo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@19edd3518ce8827eda19d82a11504b8ae8800d76 -
Trigger Event:
push
-
Statement type: