Skip to main content

A modern, comprehensive Python wrapper for Ghost Admin API with full CRUD support

Project description

PyGhost 🚀

A modern, modular Python wrapper for the Ghost Admin API. PyGhost makes it incredibly easy to interact with your Ghost CMS programmatically.

Features ✨

  • Simple & Intuitive: Easy-to-use API with clear method names
  • Modular Design: Feature-based modules for better organization
  • Complete API Coverage: Posts, Pages, Tiers, Newsletters, Offers, Members, Users, Images, Themes, and Webhooks
  • Full CRUD Operations: Create, read, update, delete for all content types
  • Flexible Content: Support for both Lexical JSON and HTML content
  • Subscription Management: Complete tier and pricing management
  • Newsletter Configuration: Email styling and sender management
  • Discount Offers: Promotional codes and discount management
  • Member Management: Subscriber CRUD operations and subscription tracking
  • User Administration: Site staff and author management with roles
  • Image Upload: Multipart file uploads and media management
  • Theme Management: Theme upload, activation, and validation
  • Webhook Integration: Event-driven webhook management and monitoring
  • Tag & Author Management: Easy handling of tags and authors
  • Robust Error Handling: Comprehensive exception handling
  • JWT Authentication: Secure token-based authentication
  • Type Hints: Full typing support for better development experience
  • Type Safety: Comprehensive enums for all fixed options with IDE autocompletion
  • Sphinx Documentation: Auto-generated API documentation support

Installation 📦

pip install -r requirements.txt

Quick Start 🚀

from pyghost import GhostClient

# Initialize the client
client = GhostClient(
    site_url="https://your-site.ghost.io",
    admin_api_key="your_admin_key:your_secret"
)

# Create a new post with type-safe enums
from pyghost.enums import PostStatus, ContentType

post = client.posts.create(
    title="My First Post",
    content="<p>Hello, World!</p>",
    status=PostStatus.PUBLISHED,
    content_type=ContentType.HTML,
    tags=["python", "ghost", "api"]
)

# Create a page
page = client.pages.create(
    title="About Us",
    content="<h1>About Our Company</h1><p>We are...</p>",
    slug="about"
)

# Create a subscription tier with type-safe enums
from pyghost.enums import Currency, TierVisibility

tier = client.tiers.create(
    name="Premium Plan",
    monthly_price=999,  # $9.99 in cents
    yearly_price=9999,  # $99.99 in cents
    currency=Currency.USD,
    visibility=TierVisibility.PUBLIC,
    benefits=["Access to all content", "Priority support"]
)

# Create a member (subscriber)
member = client.members.create(
    email="subscriber@example.com",
    name="John Subscriber",
    labels=["VIP", "Newsletter"]
)

# Upload an image
image_result = client.images.upload("path/to/image.jpg")

print(f"Created post: {post['title']}, member: {member['name']}, image: {image_result['url']}")

Type-Safe Enums 🔒

PyGhost provides comprehensive enums for all fixed options, ensuring type safety and preventing typos:

from pyghost.enums import (
    PostStatus, PageStatus, ContentType,
    OfferType, OfferDuration, OfferStatus,
    NewsletterStatus, NewsletterVisibility,
    TierVisibility, Currency,
    WebhookEvent, WebhookStatus,
    MemberStatus, UserRole, UserStatus
)

# Create content with type-safe enums
post = client.posts.create(
    title="My Blog Post",
    content="<p>Content here</p>",
    status=PostStatus.PUBLISHED,
    content_type=ContentType.HTML
)

# Create offers with enums
offer = client.offers.create(
    name="Black Friday Sale",
    code="BLACKFRIDAY50",
    type=OfferType.PERCENT,
    amount=50,
    duration=OfferDuration.ONCE,
    tier="premium-tier-id"
)

# Create newsletters with enums
newsletter = client.newsletters.create(
    name="Weekly Updates",
    status=NewsletterStatus.ACTIVE,
    visibility=NewsletterVisibility.MEMBERS
)

# Create tiers with currency enums
tier = client.tiers.create(
    name="Pro Plan",
    monthly_price=1999,  # $19.99
    currency=Currency.USD,
    visibility=TierVisibility.PUBLIC
)

# Create webhooks with event enums
webhook = client.webhooks.create(
    event=WebhookEvent.POST_PUBLISHED,
    target_url="https://example.com/webhook"
)

# Filter users by role
editors = client.users.get_editors()
authors = client.users.get_authors()

# Filter members by status
paid_members = client.members.get_paid_members()
free_members = client.members.get_free_members()

Available Enums

  • PostStatus: DRAFT, PUBLISHED, SCHEDULED, SENT
  • PageStatus: DRAFT, PUBLISHED, SCHEDULED
  • ContentType: LEXICAL, HTML
  • OfferType: PERCENT, FIXED
  • OfferDuration: ONCE, FOREVER, REPEATING
  • NewsletterStatus: ACTIVE, ARCHIVED
  • TierVisibility: PUBLIC, NONE
  • WebhookEvent: POST_ADDED, POST_DELETED, POST_PUBLISHED, etc.
  • MemberStatus: FREE, PAID, COMPED
  • UserRole: OWNER, ADMINISTRATOR, EDITOR, AUTHOR, CONTRIBUTOR
  • Currency: USD, EUR, GBP, CAD, AUD, etc.

Authentication 🔐

To use PyGhost, you need a Ghost Admin API key:

  1. Go to your Ghost Admin panel
  2. Navigate to SettingsIntegrations
  3. Create a new Custom Integration
  4. Copy the Admin API Key

The API key format is: key_id:secret_hex_string

client = GhostClient(
    site_url="https://your-ghost-site.com",
    admin_api_key="507f1f77bcf86cd799439011:3c5416c8b27c4e71ba2e1a2ac9c8f4d7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3"
)

API Reference 📚

Posts Module

The Posts module handles blog post management with full CRUD operations, publishing, and scheduling.

Creating Posts

Basic Post Creation:

from pyghost.enums import PostStatus, ContentType

# Create a draft post with Lexical content
post = client.posts.create(
    title="My New Post",
    content='{"root":{"children":[...]}}',  # Lexical JSON
    content_type=ContentType.LEXICAL
)

# Create a post with HTML content
post = client.posts.create(
    title="HTML Post",
    content="<p>Hello, <strong>World!</strong></p>",
    content_type=ContentType.HTML,
    status=PostStatus.PUBLISHED
)

Advanced Post Creation:

from pyghost.enums import PostStatus, ContentType

post = client.posts.create(
    title="Advanced Post",
    content="Post content here...",
    content_type=ContentType.LEXICAL,
    status=PostStatus.PUBLISHED,
    tags=["tutorial", "python"],
    authors=["author@example.com"],
    excerpt="This is a great post about PyGhost",
    featured=True,
    feature_image="https://example.com/image.jpg",
    meta_title="SEO Title",
    meta_description="SEO description"
)

Reading Posts

# Get a specific post by ID
post = client.posts.get("post_id_here")

# Get a post by slug
post = client.posts.get_by_slug("my-post-slug")

# List all posts
posts = client.posts.list()

# List with filtering and pagination
posts = client.posts.list(
    limit=10,
    page=1,
    filter_="status:published",
    include="tags,authors",
    order="published_at desc"
)

Updating Posts

# Get the current post to get updated_at timestamp
current_post = client.posts.get("post_id")

# Update the post
updated_post = client.posts.update(
    post_id="post_id",
    updated_at=current_post["updated_at"],
    title="New Title",
    content="Updated content...",
    tags=["updated", "post"]
)

Publishing & Scheduling

# Publish a post immediately
client.posts.publish("post_id", updated_at)

# Schedule a post for later
from datetime import datetime, timedelta
future_date = datetime.now() + timedelta(days=1)
client.posts.schedule("post_id", updated_at, future_date)

# Unpublish a post (revert to draft)
client.posts.unpublish("post_id", updated_at)

Deleting Posts

# Delete a post permanently
client.posts.delete("post_id")

Pages Module

The Pages module manages static pages with similar functionality to posts.

Creating Pages

from pyghost.enums import PageStatus

# Create a basic page
page = client.pages.create(
    title="About Us",
    content="<h1>About Our Company</h1><p>We are a leading...</p>",
    slug="about",
    meta_title="About Us - Company Information",
    meta_description="Learn more about our company"
)

# Create a page with custom settings
page = client.pages.create(
    title="Privacy Policy",
    content="<h1>Privacy Policy</h1><p>Your privacy is important...</p>",
    slug="privacy",
    status=PageStatus.PUBLISHED,
    featured=True,
    visibility="public"
)

Managing Pages

# List all pages
pages = client.pages.list()

# Get a specific page
page = client.pages.get("page_id")
page = client.pages.get_by_slug("about")

# Update a page
updated_page = client.pages.update(
    page_id="page_id",
    title="Updated About Us",
    updated_at=page["updated_at"]
)

# Publish/unpublish pages
client.pages.publish("page_id")
client.pages.unpublish("page_id")

Tiers Module

The Tiers module manages subscription tiers and pricing.

Creating Tiers

from pyghost.enums import Currency, TierVisibility

# Create a basic paid tier
tier = client.tiers.create(
    name="Premium Plan",
    description="Perfect for professionals",
    monthly_price=1999,  # $19.99 in cents
    yearly_price=19999,  # $199.99 in cents
    currency=Currency.USD,
    visibility=TierVisibility.PUBLIC,
    benefits=[
        "Access to all premium content",
        "Priority support",
        "Monthly video calls"
    ]
)

# Create a free tier
free_tier = client.tiers.create(
    name="Free Membership",
    description="Get started for free",
    monthly_price=0,
    yearly_price=0,
    currency=Currency.USD,
    benefits=["Access to free posts"]
)

Managing Tiers

# List all tiers
tiers = client.tiers.list()

# Get active tiers only
active_tiers = client.tiers.get_active_tiers()

# Update tier pricing
updated_tier = client.tiers.update(
    tier_id="tier_id",
    monthly_price=2499,  # Increase to $24.99
    benefits=[
        "Everything in previous version",
        "New premium feature"
    ]
)

# Archive/activate tiers
client.tiers.archive("tier_id")
client.tiers.activate("tier_id")

Newsletters Module

The Newsletters module manages email newsletter configuration and styling.

Creating Newsletters

from pyghost.enums import NewsletterStatus, NewsletterSenderReplyTo

# Create a newsletter with custom styling
newsletter = client.newsletters.create(
    name="Weekly Digest",
    description="Our weekly roundup of content",
    sender_name="Editorial Team",
    sender_reply_to=NewsletterSenderReplyTo.NEWSLETTER,
    status=NewsletterStatus.ACTIVE,
    title_font_category="serif",
    title_alignment="center",
    show_badge=False,
    subscribe_on_signup=True
)

# Create a minimal newsletter
minimal_newsletter = client.newsletters.create(
    name="Product Updates",
    description="Important product announcements",
    sender_name="Product Team",
    show_header_icon=False,
    show_feature_image=False,
    subscribe_on_signup=False
)

Managing Newsletters

# List newsletters
newsletters = client.newsletters.list()
active_newsletters = client.newsletters.get_active_newsletters()

# Update newsletter styling
updated_newsletter = client.newsletters.update(
    newsletter_id="newsletter_id",
    title_alignment="left",
    body_font_category="sans_serif",
    footer_content="<p>Thanks for reading!</p>"
)

# Archive/activate newsletters
client.newsletters.archive("newsletter_id")
client.newsletters.activate("newsletter_id")

Offers Module

The Offers module manages discount offers and promotional codes.

Creating Offers

from pyghost.enums import OfferType, OfferDuration, OfferCadence, Currency

# Create a percentage discount
percent_offer = client.offers.create(
    name="Black Friday Sale",
    code="BLACKFRIDAY2024",
    display_title="50% Off Annual Plans",
    display_description="Limited time - 50% off all annual subscriptions",
    type=OfferType.PERCENT,
    amount=50,  # 50% discount
    duration=OfferDuration.ONCE,  # Apply to first payment only
    tier_id="tier_id",
    cadence=OfferCadence.YEAR
)

# Create a fixed amount discount
fixed_offer = client.offers.create(
    name="Welcome Bonus",
    code="WELCOME10",
    display_title="$10 Off Your First Month",
    display_description="New customer special offer",
    type=OfferType.FIXED,
    amount=1000,  # $10.00 in cents
    duration=OfferDuration.ONCE,
    tier_id="tier_id",
    cadence=OfferCadence.MONTH,
    currency=Currency.USD
)

Managing Offers

# List offers
offers = client.offers.list(include="tier")
active_offers = client.offers.get_active_offers()

# Get offer by code
offer = client.offers.get_by_code("BLACKFRIDAY2024")

# Update offer
updated_offer = client.offers.update(
    offer_id="offer_id",
    display_title="Extended: 50% Off!",
    amount=60  # Increase discount to 60%
)

# Calculate discount
calculation = client.offers.calculate_discount(offer, 2999)  # $29.99
print(f"Final price: ${calculation['final_price']/100:.2f}")

# Generate offer URL
offer_url = client.offers.generate_offer_url("BLACKFRIDAY2024", "https://mysite.com")

Members Module

The Members module manages subscribers and their relationships with newsletters, tiers, and labels.

Creating Members

# Create a basic member
member = client.members.create(
    email="subscriber@example.com",
    name="John Subscriber"
)

# Create a member with labels and newsletter subscriptions
advanced_member = client.members.create(
    email="premium@example.com",
    name="Premium Subscriber",
    note="VIP customer from email campaign",
    labels=["VIP", "Premium", "Newsletter"],
    newsletters=["newsletter_id_1", "newsletter_id_2"],
    tiers=["tier_id_1"]
)

Managing Members

# List all members
members = client.members.list()

# Get members with filtering
paid_members = client.members.list(
    filter_="status:paid",
    include="newsletters,tiers",
    order="created_at desc"
)

# Get a specific member
member = client.members.get("member_id", include="labels,newsletters")
member = client.members.get_by_email("subscriber@example.com")

# Update member information
updated_member = client.members.update(
    member_id="member_id",
    name="Updated Name",
    note="Updated customer status",
    labels=["Premium", "Updated"]
)

Label Management

# Add labels to a member (preserves existing labels)
client.members.add_labels("member_id", ["New Label", "Another Label"])

# Remove specific labels
client.members.remove_labels("member_id", ["Old Label", "Expired"])

# Get members by label
vip_members = client.members.get_members_by_label("VIP")

Newsletter Subscriptions

# Subscribe to additional newsletters
client.members.subscribe_to_newsletters(
    "member_id", 
    ["newsletter_id_1", "newsletter_id_2"]
)

# Unsubscribe from newsletters
client.members.unsubscribe_from_newsletters(
    "member_id", 
    ["newsletter_id_1"]
)

Member Analytics

# Get member statistics
stats = client.members.get_member_statistics()
print(f"Total: {stats['total']}, Paid: {stats['paid']}, Free: {stats['free']}")

# Get different member types
paid_members = client.members.get_paid_members(include="tiers")
free_members = client.members.get_free_members()

Users Module

The Users module manages site staff and authors (different from members/subscribers).

Managing User Profiles

# List all users
users = client.users.list(include="count.posts,roles")

# Get a specific user
user = client.users.get("user_id", include="count.posts,roles")
user = client.users.get_by_email("author@example.com")
user = client.users.get_by_slug("author-slug")

# Update user profile
updated_user = client.users.update(
    user_id="user_id",
    name="John Author",
    bio="Senior content writer with 5 years experience",
    website="https://johnauthor.com",
    location="San Francisco, CA",
    twitter="@johnauthor",
    meta_title="John Author - Technical Writer",
    meta_description="Experienced technical writer and content creator"
)

Role-Based User Management

# Get users by role
owners = client.users.get_owners()
administrators = client.users.get_administrators()
editors = client.users.get_editors()
authors = client.users.get_authors(include="count.posts")
contributors = client.users.get_contributors()

# Get available roles
roles = client.users.get_user_roles()
for role in roles:
    print(f"Role: {role['name']} - {role['description']}")

# Get user permissions
permissions = client.users.get_user_permissions("user_id")

Notification Settings

# Update notification preferences
client.users.update_notification_settings(
    "user_id",
    comment_notifications=True,
    mention_notifications=True,
    milestone_notifications=False,
    free_member_signup_notification=True,
    paid_subscription_started_notification=True
)

User Analytics

# Get user statistics
stats = client.users.get_user_statistics()
print(f"Total Users: {stats['total']}, Authors: {stats['authors']}")

# Get active users
active_users = client.users.get_active_users()

Images Module

The Images module handles file uploads and media management.

Basic Image Upload

# Upload from file path
result = client.images.upload("/path/to/image.jpg")
print(f"Image URL: {result['url']}")
print(f"Reference: {result['ref']}")

# Upload from file object
with open("image.png", "rb") as f:
    result = client.images.upload(f, "image.png")

Advanced Upload Features

# Upload multiple images
image_paths = ["/path/to/image1.jpg", "/path/to/image2.png"]
results = client.images.upload_multiple(image_paths)

# Upload from URL
result = client.images.upload_from_url(
    "https://example.com/image.jpg",
    "my-image.jpg"
)

# Upload without validation (use with caution)
result = client.images.upload("image.jpg", validate=False)

Image Validation

# Validate a single image
is_valid = client.images.validate_image_path("/path/to/image.jpg")

# Get detailed image information
info = client.images.get_image_info("/path/to/image.jpg")
print(f"Size: {info['size_mb']} MB, Format: {info['format']}")
print(f"Dimensions: {info['width']}x{info['height']}")
print(f"Supported: {info['is_supported']}")

# Batch validation
files = ["/path/to/image1.jpg", "/path/to/image2.png"]
results = client.images.batch_validate(files)
print(f"Valid: {results['valid_count']}, Invalid: {results['invalid_count']}")

Supported Formats

# Supported image formats
supported_formats = client.images.SUPPORTED_FORMATS
print(f"Supported formats: {', '.join(sorted(supported_formats))}")

# Maximum file size
max_size_mb = client.images.MAX_FILE_SIZE / (1024 * 1024)
print(f"Maximum file size: {max_size_mb} MB")

Themes Module

The Themes module handles Ghost theme upload, activation, and management.

Theme Upload and Activation

# Upload a theme from file path
uploaded_theme = client.themes.upload_from_file(
    "/path/to/my-theme.zip",
    activate=True  # Activate immediately after upload
)

# Upload from file object
with open("theme.zip", "rb") as theme_file:
    theme = client.themes.upload_from_file_object(theme_file)

# Activate an uploaded theme
activated_theme = client.themes.activate("theme-name")

Theme Validation

# Validate theme structure before upload
validation = client.themes.validate_theme_structure("/path/to/theme.zip")
print(f"Valid: {validation['valid']}")
print(f"Templates: {len(validation['templates'])}")

# Get theme information
info = client.themes.get_theme_info("/path/to/theme.zip")
print(f"Name: {info['name']}")
print(f"Version: {info['version']}")
print(f"Description: {info['description']}")

# Check supported formats
formats = client.themes.get_supported_formats()
is_valid = client.themes.validate_theme_format("theme.zip")

Webhooks Module

The Webhooks module manages event-driven webhooks for real-time integrations.

Creating Webhooks

from pyghost.enums import WebhookEvent

# Create a basic webhook
webhook = client.webhooks.create(
    event=WebhookEvent.POST_PUBLISHED,
    target_url="https://example.com/webhook",
    name="Post Publication Hook"
)

# Create webhook with security
secure_webhook = client.webhooks.create(
    event=WebhookEvent.MEMBER_ADDED,
    target_url="https://example.com/new-member",
    name="New Member Webhook",
    secret="your-secret-key",
    api_version="v5.0"
)

# Use convenience methods (accepts both enums and strings)
post_hook = client.webhooks.create_post_webhook(
    "https://example.com/post-hook",
    event=WebhookEvent.POST_EDITED
)

member_hook = client.webhooks.create_member_webhook(
    "https://example.com/member-hook"
)

Managing Webhooks

# List all webhooks
webhooks = client.webhooks.list()

# Get specific webhook
webhook = client.webhooks.get("webhook_id")

# Update webhook
updated = client.webhooks.update(
    webhook_id="webhook_id",
    target_url="https://new-endpoint.com/webhook",
    name="Updated Webhook Name"
)

# Delete webhook
success = client.webhooks.delete("webhook_id")

# Bulk delete webhooks
results = client.webhooks.bulk_delete_webhooks([
    "webhook_id_1", "webhook_id_2"
])

Webhook Events and Monitoring

# Get available events
events = client.webhooks.get_webhook_events()
print(f"Available events: {', '.join(events)}")

# Validate event types
is_valid = client.webhooks.validate_webhook_event("post.published")

# Get webhooks by event
post_webhooks = client.webhooks.get_webhooks_by_event("post.published")

# Get webhook statistics
stats = client.webhooks.get_webhook_statistics()
print(f"Total: {stats['total']}, Active: {stats['active']}")

# Get active webhooks only
active = client.webhooks.get_active_webhooks()

Working with Tags and Authors 🏷️

Tags

# Using tag names (will create tags if they don't exist)
post = client.posts.create(
    title="Tagged Post",
    tags=["python", "tutorial", "beginner"]
)

# Using tag objects for more control
post = client.posts.create(
    title="Tagged Post",
    tags=[
        {"name": "python", "description": "Python programming"},
        {"name": "#internal"}  # Hidden tag
    ]
)

Authors

# Using author emails
post = client.posts.create(
    title="Multi-Author Post",
    authors=["author1@example.com", "author2@example.com"]
)

# Using author IDs
post = client.posts.create(
    title="Post by ID",
    authors=[
        {"id": "author_id_1"},
        {"id": "author_id_2"}
    ]
)

Error Handling 🛡️

PyGhost provides specific exception types for different error scenarios:

from pyghost import GhostClient
from pyghost.exceptions import (
    GhostAPIError,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError
)

try:
    client = GhostClient(site_url="...", admin_api_key="...")
    post = client.posts.create(title="Test Post")
    
except AuthenticationError as e:
    print(f"Authentication failed: {e}")
    
except ValidationError as e:
    print(f"Validation error: {e}")
    
except NotFoundError as e:
    print(f"Resource not found: {e}")
    
except RateLimitError as e:
    print(f"Rate limit exceeded: {e}")
    
except GhostAPIError as e:
    print(f"API error: {e}")

Content Formats 📝

Lexical JSON Format

Ghost's modern content format. You can create Lexical content programmatically:

lexical_content = {
    "root": {
        "children": [
            {
                "children": [
                    {
                        "detail": 0,
                        "format": 0,
                        "mode": "normal",
                        "style": "",
                        "text": "Hello, World!",
                        "type": "extended-text",
                        "version": 1
                    }
                ],
                "direction": "ltr",
                "format": "",
                "indent": 0,
                "type": "paragraph",
                "version": 1
            }
        ],
        "direction": "ltr",
        "format": "",
        "indent": 0,
        "type": "root",
        "version": 1
    }
}

from pyghost.enums import ContentType

post = client.posts.create(
    title="Lexical Post",
    content=json.dumps(lexical_content),
    content_type=ContentType.LEXICAL
)

HTML Format

For traditional HTML content:

from pyghost.enums import ContentType, PostStatus

post = client.posts.create(
    title="HTML Post",
    content="<p>Hello, <strong>World!</strong></p>",
    content_type=ContentType.HTML,
    status=PostStatus.PUBLISHED
)

Examples 💡

Check out the examples/ directory for comprehensive examples:

  • basic_usage.py: Simple post creation and management
  • bulk_operations.py: Working with multiple posts efficiently
  • pages_usage.py: Complete pages management examples
  • tiers_usage.py: Subscription tier and pricing examples
  • newsletters_usage.py: Newsletter configuration and styling
  • offers_usage.py: Discount offers and promotional codes
  • members_usage.py: Member management and subscription tracking
  • users_usage.py: User profile and role management examples
  • images_usage.py: Image upload and media management examples
  • themes_usage.py: Theme upload, validation, and management examples
  • webhooks_usage.py: Webhook creation, monitoring, and event handling

Each example file includes:

  • Basic CRUD operations
  • Advanced features and utilities
  • Error handling best practices
  • Cleanup procedures
  • Production usage tips

API Limitations ⚠️

  • JWT tokens expire after 5 minutes (handled automatically)
  • Rate limiting applies (usually 500 requests per hour)
  • Some operations require specific permissions
  • updated_at timestamp is required for updates to prevent conflicts

Development 🔧

Setting Up Development Environment

# Clone the repository
git clone <repository-url>
cd pyghost

# Install dependencies
pip install -r requirements.txt

# Install in development mode
pip install -e .

Running Tests

# Run tests (when available)
python -m pytest tests/

# Run with coverage
python -m pytest tests/ --cov=pyghost

Contributing 🤝

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License 📄

This project is licensed under the MIT License - see the LICENSE file for details.

Support 💬

Roadmap 🗺️

  • Posts API support ✅
  • Pages API support ✅
  • Tiers API support ✅
  • Newsletters API support ✅
  • Offers API support ✅
  • Members API support ✅
  • Users and roles API ✅
  • Image upload support ✅
  • Themes API support ✅
  • Webhooks API support ✅
  • Site settings API
  • Tags API support
  • Bulk operations optimization
  • Async/await support
  • CLI tool
  • Enhanced testing suite

Made with ❤️ for the Ghost community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyghost-1.0.3.tar.gz (83.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyghost-1.0.3-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file pyghost-1.0.3.tar.gz.

File metadata

  • Download URL: pyghost-1.0.3.tar.gz
  • Upload date:
  • Size: 83.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for pyghost-1.0.3.tar.gz
Algorithm Hash digest
SHA256 0b00548c33487aa38f4acc2e6ff6db7d1a6fc8b897f916c95b687e23709042d1
MD5 987e5defdcfbcf4b6588fe0655c83c06
BLAKE2b-256 ff7b83dff76f6e61951bebd528ee1ab0ec7e9d8bc49dbc10033ba3ad3e2892ce

See more details on using hashes here.

File details

Details for the file pyghost-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: pyghost-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for pyghost-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 105a49b0547b27e778d8386e369d5aa09e3e4c85192f87e684f65b20a645898f
MD5 6356b93b77f28211b154485c508f6cee
BLAKE2b-256 1fabf7d3614b5a725350f3de860fd47723d418a3b6a6de2f3a15c6760b4e2167

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page