telegraph-api
A complete Python wrapper for the Telegraph API.
Related Projects
This is part of the Telegraph tools ecosystem:
| Project | Description | Package |
|---|---|---|
| telegraph-mcp | MCP Server for AI assistants | |
| telegraph-js | JavaScript/TypeScript library | |
| telegraph-api-py (this) | Python library |
Features
- Full support for all 9 Telegraph API methods
- Both synchronous and asynchronous clients
- Type hints for better IDE support and type checking
- HTML and Markdown content support
- Automatic content parsing and validation
- Comprehensive error handling
- Context manager support
- Zero dependencies for sync client (only
requests) - Optional async support with
aiohttp - Image Upload - Upload images and videos to Telegraph
- Templates - Pre-built templates for common content types
- Export & Backup - Export pages to Markdown/HTML and backup accounts
Installation
Basic installation (synchronous client only)
pip install telegraph-api-py
With async support
pip install telegraph-api-py[async]
For development
pip install telegraph-api-py[dev]
Quick Start
Synchronous Usage
from telegraph import Telegraph
# Create a Telegraph client
tg = Telegraph()
# Create an account
account = tg.create_account(
short_name="MyBot",
author_name="John Doe",
author_url="https://example.com"
)
print(f"Access token: {account.access_token}")
# Create a page with HTML content
page = tg.create_page(
title="Hello World",
content="<p>This is my <b>first</b> Telegraph page!</p>",
author_name="John Doe"
)
print(f"Page URL: {page.url}")
print(f"Page views: {page.views}")
Asynchronous Usage
import asyncio
from telegraph import AsyncTelegraph
async def main():
async with AsyncTelegraph() as tg:
# Create an account
account = await tg.create_account(
short_name="MyAsyncBot",
author_name="Jane Doe"
)
# Create a page
page = await tg.create_page(
title="Async Hello World",
content="<p>This page was created asynchronously!</p>"
)
print(f"Page URL: {page.url}")
asyncio.run(main())
API Methods
Account Methods
Create Account
account = tg.create_account(
short_name="MyBot", # Required: 1-32 characters
author_name="John Doe", # Optional: 0-128 characters
author_url="https://example.com" # Optional: 0-512 characters
)
# Returns Account object with access_token
print(account.access_token)
Edit Account Info
account = tg.edit_account_info(
short_name="NewName",
author_name="New Author",
author_url="https://newurl.com"
)
Get Account Info
account = tg.get_account_info(
fields=["short_name", "author_name", "page_count"]
)
print(f"Pages created: {account.page_count}")
Revoke Access Token
account = tg.revoke_access_token()
print(f"New access token: {account.access_token}")
print(f"Auth URL: {account.auth_url}")
Page Methods
Create Page
# With HTML content
page = tg.create_page(
title="My Page",
content="<p>Hello <b>world</b>!</p>",
author_name="John Doe",
author_url="https://example.com",
return_content=False
)
# With Markdown content
page = tg.create_page(
title="My Markdown Page",
content="# Hello\n\nThis is **bold** and this is *italic*.",
content_format="markdown"
)
# With Node array
from telegraph import NodeElement
nodes = [
NodeElement(tag='p', children=['Hello ', NodeElement(tag='b', children=['world'])])
]
page = tg.create_page(
title="My Node Page",
content=nodes
)
Edit Page
page = tg.edit_page(
path="My-Page-12-15",
title="Updated Title",
content="<p>Updated content</p>",
return_content=True
)
Get Page
page = tg.get_page(
path="My-Page-12-15",
return_content=True
)
print(f"Title: {page.title}")
print(f"Views: {page.views}")
print(f"Content: {page.content}")
Get Page List
page_list = tg.get_page_list(
offset=0,
limit=50
)
print(f"Total pages: {page_list.total_count}")
for page in page_list.pages:
print(f"- {page.title}: {page.url}")
Get Page Views
# Get total views
views = tg.get_views(path="My-Page-12-15")
print(f"Total views: {views.views}")
# Get views for specific date
views = tg.get_views(
path="My-Page-12-15",
year=2025,
month=12,
day=7,
hour=12 # Optional
)
print(f"Views: {views.views}")
Content Formats
HTML Content
Telegraph supports the following HTML tags:
<a>- links (requireshrefattribute)<aside>- aside block<b>,<strong>- bold text<blockquote>- blockquote<br>- line break<code>- inline code<em>,<i>- italic text<figcaption>- figure caption<figure>- figure<h3>,<h4>- headers<hr>- horizontal rule<iframe>- iframe (requiressrcattribute)<img>- image (requiressrcattribute)<li>- list item<ol>- ordered list<p>- paragraph<pre>- preformatted text<s>- strikethrough<u>- underline<ul>- unordered list<video>- video (requiressrcattribute)
Example:
content = """
<h3>Article Title</h3>
<p>This is a paragraph with <b>bold</b> and <i>italic</i> text.</p>
<blockquote>This is a quote</blockquote>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
<a href="https://example.com">Link</a>
<img src="https://example.com/image.jpg"/>
"""
page = tg.create_page(title="My Article", content=content)
Markdown Content
The library includes a Markdown to HTML converter:
markdown = """
# Main Title
This is a paragraph with **bold** and *italic* text.
## Subheading
> This is a blockquote
### Features
- Item 1
- Item 2
- Item 3
1. First
2. Second
3. Third
[Link text](https://example.com)

`inline code`
code block
"""
page = tg.create_page(
title="Markdown Example",
content=markdown,
content_format="markdown"
)
Node Array Content
For maximum control, use Node arrays:
from telegraph import NodeElement
content = [
NodeElement(tag='h3', children=['Title']),
NodeElement(tag='p', children=[
'This is ',
NodeElement(tag='b', children=['bold']),
' text.'
]),
NodeElement(tag='img', attrs={'src': 'https://example.com/image.jpg'})
]
page = tg.create_page(title="Node Example", content=content)
Error Handling
The library provides specific exception types:
from telegraph import Telegraph, TelegraphError, TelegraphValidationError, TelegraphAPIError
tg = Telegraph()
try:
page = tg.create_page(
title="Test",
content="<p>Test</p>"
)
except TelegraphValidationError as e:
print(f"Validation error: {e.message}")
print(f"Field: {e.field}")
except TelegraphAPIError as e:
print(f"API error: {e.message}")
except TelegraphError as e:
print(f"General error: {e.message}")
Exception hierarchy:
TelegraphError- Base exceptionTelegraphAPIError- API returned an errorTelegraphHTTPError- HTTP error occurredTelegraphConnectionError- Connection errorTelegraphValidationError- Input validation failed
Context Manager
Both clients support context managers for automatic cleanup:
# Synchronous
with Telegraph() as tg:
account = tg.create_account(short_name="MyBot")
page = tg.create_page(title="Test", content="<p>Test</p>")
# Session automatically closed
# Asynchronous
async with AsyncTelegraph() as tg:
account = await tg.create_account(short_name="MyBot")
page = await tg.create_page(title="Test", content="<p>Test</p>")
# Session automatically closed
Using Access Tokens
You can store the access token and reuse it:
# Create account and get token
tg = Telegraph()
account = tg.create_account(short_name="MyBot")
token = account.access_token
# Save token to database/file...
# Later, reuse the token
tg = Telegraph(access_token=token)
page = tg.create_page(title="Test", content="<p>Test</p>")
# Or pass explicitly
page = tg.create_page(
access_token="different_token",
title="Test",
content="<p>Test</p>"
)
Utility Functions
The library provides utility functions for content manipulation:
from telegraph import html_to_nodes, markdown_to_html, parse_content, nodes_to_json
# Convert HTML to Node array
nodes = html_to_nodes("<p>Hello <b>world</b></p>")
# Convert Markdown to HTML
html = markdown_to_html("# Title\n\nThis is **bold**")
# Parse content (auto-detect format)
nodes = parse_content("<p>HTML content</p>", format='html')
nodes = parse_content("# Markdown content", format='markdown')
# Convert nodes to JSON-serializable format
json_nodes = nodes_to_json(nodes)
# Convert nodes back to Markdown
from telegraph import nodes_to_markdown
markdown = nodes_to_markdown(page.content)
# Convert nodes back to HTML
from telegraph import nodes_to_html
html = nodes_to_html(page.content)
Image Upload
Upload images and videos to Telegraph:
# Upload from file path
result = tg.upload_image(file_path="./image.jpg")
print(f"Uploaded: {result.url}")
# Upload from base64
import base64
with open("image.png", "rb") as f:
data = base64.b64encode(f.read()).decode()
result = tg.upload_image(
base64_data=data,
content_type="image/png",
filename="image.png"
)
print(f"Uploaded: {result.url}")
Async version:
async with AsyncTelegraph() as tg:
result = await tg.upload_image(file_path="./image.jpg")
Supported formats: JPEG, PNG, GIF, MP4
Templates
Use pre-built templates for common content types:
from telegraph import list_templates, create_from_template
# List available templates
templates = list_templates()
# Returns: blog_post, documentation, article, changelog, tutorial
# Create content from template
nodes = create_from_template('blog_post', {
'title': 'My Blog Post',
'intro': 'This is the introduction',
'sections': [
{'heading': 'Section 1', 'content': 'First section content'},
{'heading': 'Section 2', 'content': 'Second section content'}
],
'conclusion': 'Final thoughts'
})
# Use in create_page
page = tg.create_page(
title='My Blog Post',
content=nodes
)
Available Templates
| Template | Required Fields | Optional Fields |
|---|---|---|
blog_post |
title, intro, sections[] | conclusion |
documentation |
title, overview | installation, usage, api_reference[] |
article |
title, body[] | subtitle |
changelog |
title, version, date | added[], changed[], fixed[] |
tutorial |
title, description, steps[] | prerequisites[], conclusion |
Export & Backup
Export pages to Markdown or HTML, and backup entire accounts:
from telegraph import export_page, backup_account
# Export a single page
exported = export_page(
path='My-Page-12-15',
format='markdown' # or 'html'
)
print(exported.content)
# Backup all pages from an account
backup = backup_account(
access_token='your-token',
format='markdown',
limit=100 # max pages to export
)
print(f"Exported {backup.exported_count} of {backup.total_count} pages")
for page in backup.pages:
print(f"{page.title}: {page.content[:100]}...")
Async versions are also available:
from telegraph import export_page_async, backup_account_async
async with AsyncTelegraph() as tg:
exported = await export_page_async(path='My-Page-12-15')
backup = await backup_account_async(access_token='token')
Advanced Usage
Custom Timeout
# Synchronous client with custom timeout
tg = Telegraph(timeout=60) # 60 seconds
# Asynchronous client with custom timeout
tg = AsyncTelegraph(timeout=60)
Custom Base URL
# Use custom Telegraph API endpoint
tg = Telegraph(base_url="https://custom-api.example.com")
Type Hints
The library is fully typed. Use with mypy or other type checkers:
from telegraph import Telegraph, Account, Page
tg: Telegraph = Telegraph()
account: Account = tg.create_account(short_name="MyBot")
page: Page = tg.create_page(title="Test", content="<p>Test</p>")
Testing
Run tests:
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=telegraph --cov-report=html
Requirements
- Python 3.9+
requests(for synchronous client)aiohttp(optional, for asynchronous client)
License
MIT License. See LICENSE file for details.
Links
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Changelog
Version 1.0.0 (2025-12-07)
- Initial release
- Full support for all 9 Telegraph API methods
- Synchronous and asynchronous clients
- HTML and Markdown content support
- Comprehensive error handling
- Type hints
- Full test coverage
Metadata
Release files for telegraph-api-py 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| telegraph_api_py-1.2.0.tar.gz | 26.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| telegraph_api_py-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.4 kB
Release files / telegraph_api_py-1.2.0.tar.gz
| Download URL | telegraph_api_py-1.2.0.tar.gz |
|---|---|
| Size | 26.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
170f116e4286cd9a8b785145a82fb9c939cf41a5a26a7afab0ec1d50e0339d17
|
|
BLAKE2b-256 checksum How to use checksums |
554527ee9d12da8425c52a3bc97d65a2ed6feb87db337bce30e63463c2e00160
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / telegraph_api_py-1.2.0-py3-none-any.whl
| Download URL | telegraph_api_py-1.2.0-py3-none-any.whl |
|---|---|
| Size | 24.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6a98b3fa894a925464d77ff763c96673adbfa22a1e09c2e5157813a686690fed
|
|
BLAKE2b-256 checksum How to use checksums |
ecf6e55eee33052f2d544984503f4b93b2fe626b23d6bdf43d0dd666382836fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|