Skip to main content

is a Simple, FileBase and Document Oriented database

Project description

🐾 PantherDB

PyPI PyVersion Downloads license

A lightweight, file-based NoSQL database for Python with MongoDB-like interface and optional encryption support.

Features

  • Document-Oriented: Store and query data as flexible JSON documents
  • File-Based: No server setup required, data stored in JSON files
  • Encryption Support: Optional Fernet encryption for sensitive data
  • MongoDB-like API: Familiar interface with collections and documents
  • Thread-Safe: Built-in thread safety with RLock
  • Cursor Support: Advanced querying with sorting, limiting, and pagination
  • Singleton Pattern: Efficient connection management per database
  • Pure Python: Built with Python 3.8+ and standard type hints

Installation

# Basic installation
pip install pantherdb

# With encryption support
pip install pantherdb[full]

Quick Start

from pantherdb import PantherDB

# Create a database
db = PantherDB('my_database')

# Get a collection
users = db.collection('users')

# Insert a document
user = users.insert_one(
    name='John Doe',
    email='john@example.com',
    age=30,
    is_active=True
)

# Find documents
john = users.find_one(name='John Doe')
all_users = users.find()
active_users = users.find(is_active=True)

# Update a document
john.update(age=31)

# Delete a document
john.delete()

Database Operations

Creating a Database

from pantherdb import PantherDB

# Basic database (creates database.json)
db = PantherDB('my_app')

# Encrypted database (creates database.pdb)
from cryptography.fernet import Fernet
key = Fernet.generate_key()  # Store this key securely!
db = PantherDB('secure_app', secret_key=key)

# Return raw dictionaries instead of PantherDocument objects
db = PantherDB('my_app', return_dict=True)

# Return Cursor objects for find operations
db = PantherDB('my_app', return_cursor=True)

Collection Management

# Access a collection
users = db.collection('users')

# Delete a collection and all its documents
users.drop()

CRUD Operations

Create

# Insert a single document
user = users.insert_one(
    name='Alice',
    email='alice@example.com',
    age=25,
    tags=['python', 'developer']
)

# Documents automatically get a unique _id field
print(user.id)  # ULID string

Read

# Find one document
user = users.find_one(name='Alice')
user = users.find_one()  # Get first document

# Find first document (alias)
user = users.first(name='Alice')
user = users.first()  # Get first document

# Find last document
user = users.last(name='Alice')
user = users.last()  # Get last document

# Find multiple documents
all_users = users.find()
alice_users = users.find(name='Alice')

# Count documents
total_users = users.count()
alice_count = users.count(name='Alice')

Update

# Update a specific document
user = users.find_one(name='Alice')
user.update(age=26, email='alice.new@example.com')

# Update with filter
updated = users.update_one(
    {'name': 'Alice'}, 
    age=26, 
    email='alice.new@example.com'
)

# Update multiple documents
updated_count = users.update_many(
    {'age': 25}, 
    age=26
)

Delete

# Delete a specific document
user = users.find_one(name='Alice')
user.delete()

# Delete with filter
deleted = users.delete_one(name='Alice')

# Delete multiple documents
deleted_count = users.delete_many(age=25)

Document Operations

Accessing Document Fields

user = users.find_one(name='Alice')

# Access fields as attributes
print(user.name)      # 'Alice'
print(user.age)       # 25
print(user.email)     # 'alice@example.com'

# Access fields as dictionary items
print(user['name'])   # 'Alice'
print(user['age'])    # 25

# Get document ID
print(user.id)        # ULID string

Modifying Documents

user = users.find_one(name='Alice')

# Set fields directly
user.age = 26
user.status = 'active'
user.save()  # Save changes to database

# Update multiple fields
user.update(
    age=26,
    status='active',
    last_login='2023-01-01'
)

# Get JSON representation
json_data = user.json()
print(json_data)  # '{"_id": "...", "name": "Alice", "age": 26}'

Cursor Operations

When using return_cursor=True, find operations return Cursor objects with advanced features:

# Enable cursor mode
db = PantherDB('my_app', return_cursor=True)
users = db.collection('users')

# Basic cursor iteration
cursor = users.find()
for user in cursor:
    print(user.name)

# Sorting
cursor = users.find().sort('age', -1)  # Descending by age
cursor = users.find().sort('name', 1)  # Ascending by name

# Limiting and skipping
cursor = users.find().limit(10).skip(5)  # Pagination

# Chaining operations
cursor = users.find(age=18).sort('age', -1).limit(5)

# Async iteration
async for user in cursor:
    print(user.name)

Encryption

For sensitive data, PantherDB supports database encryption:

from pantherdb import PantherDB
from cryptography.fernet import Fernet

# Generate a key (store this securely!)
key = Fernet.generate_key()

# Create encrypted database
db = PantherDB('secure_database', secret_key=key)

# All operations work the same way
users = db.collection('users')
user = users.insert_one(name='Secret User', password='hashed_password')

Important Notes:

  • Store your encryption key securely
  • Don't generate a new key on every run
  • Losing the key means losing access to your data
  • Encrypted databases use .pdb extension, unencrypted use .json

Advanced Features

Singleton Pattern

PantherDB implements a singleton pattern per database file:

# Multiple instances with same name share data
db1 = PantherDB('my_app')
db2 = PantherDB('my_app')

# Both instances point to the same database
users1 = db1.collection('users')
users2 = db2.collection('users')

# Changes in one instance are visible in the other
users1.insert_one(name='Alice')
user = users2.find_one(name='Alice')  # Found!

Thread Safety

All operations are thread-safe:

import threading

def insert_user(name):
    db = PantherDB('my_app')
    users = db.collection('users')
    users.insert_one(name=name)

# Safe to use from multiple threads
threads = [
    threading.Thread(target=insert_user, args=(f'User{i}',))
    for i in range(10)
]

for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

Database Information

db = PantherDB('my_app')

# String representation shows collections and document counts
print(db)
# PantherDB(
#     users: 5 documents,
#     posts: 10 documents
# )

# Collection information
users = db.collection('users')
print(users)
# PantherCollection(
#     collection_name: users
#     name: str
#     age: int
#     email: str
# )

Error Handling

PantherDB raises PantherDBException for database errors:

from pantherdb import PantherDB, PantherDBException

try:
    db = PantherDB('corrupted_db', secret_key=wrong_key)
except PantherDBException as e:
    print(f"Database error: {e}")

License

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


If you find Panther useful, please give it a star! ⭐️

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

pantherdb-2.3.1.tar.gz (20.6 kB view details)

Uploaded Source

Built Distribution

pantherdb-2.3.1-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file pantherdb-2.3.1.tar.gz.

File metadata

  • Download URL: pantherdb-2.3.1.tar.gz
  • Upload date:
  • Size: 20.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for pantherdb-2.3.1.tar.gz
Algorithm Hash digest
SHA256 6c2efa40629751625433a6b8436b547436e2abc66bcfc2dca4585b7da5ed8835
MD5 e69148dc65ad252cb825e312af51590f
BLAKE2b-256 a58eb2674a9592537143aaaf17a3e24cb5cccbe411a00103380f17ee96ba270c

See more details on using hashes here.

File details

Details for the file pantherdb-2.3.1-py3-none-any.whl.

File metadata

  • Download URL: pantherdb-2.3.1-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for pantherdb-2.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 84febd7501dc8c169fd69d41d4218afd2fa42c199cc4dbc92c60750fee5a1c9e
MD5 18656f3e8720d684e8a7449d6f20bb9c
BLAKE2b-256 1370d65e6749163ca868c6b44a983cbf9e790d075fe7ecd1fed984302f1d000e

See more details on using hashes here.

Supported by

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