Skip to content

adamfils/PyGhost

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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 Settings β†’ Integrations
  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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages