Skip to main content

An asynchronous object-spatial Python library for persistence and business logic application layers.

Project description

jvspatial

An async-first Python library for building graph-based spatial applications with FastAPI integration. Provides entity-centric database operations with automatic context management.

GitHub release (latest by date) GitHub Workflow Status GitHub issues GitHub pull requests GitHub

Table of Contents

Overview

jvspatial is an async-first Python library for building graph-based spatial applications with FastAPI integration. It provides entity-centric database operations with automatic context management.

Inspired by Jaseci's object-spatial paradigm and leveraging Python's async capabilities, jvspatial empowers developers to model complex relationships, traverse object graphs, and implement agent-based architectures that scale with modern cloud-native concurrency requirements.

🚀 Serverless Ready: Deploy to AWS Lambda with zero configuration changes. Use LambdaServer and your FastAPI app is automatically wrapped with Mangum for Lambda compatibility. Includes native DynamoDB support for persistent storage in serverless environments.

Key Design Principles:

  • Hierarchy: Object → Node → Edge/Walker inheritance
  • Entity-Centric: Direct database operations via entity methods
  • Unified Decorators: @attribute for entity attributes, @endpoint for API endpoints
  • Automatic Context: Server automatically provides database context to entities
  • Essential CRUD: Core database operations with pagination support
  • Unified Configuration: Single Config class for all settings
  • Async-First: Built for modern Python async/await patterns

Key Features

🎯 Inheritance Hierarchy

  • Object: Base class for all entities
  • Node: Graph nodes with spatial data (inherits from Object)
  • Edge: Relationships between nodes (inherits from Object)
  • Walker: Graph traversal and pathfinding (inherits from Object)
  • Root: Singleton root node (inherits from Node)

🎨 Unified Decorator System

  • @attribute - Define entity attributes with protection, transient flags, and validation
  • @endpoint - Unified endpoint decorator for both functions and Walker classes
  • Automatic parameter and response schema generation

🗄️ Entity-Centric Database Operations

  • Entity methods: Entity.get(), Entity.find(), Entity.create(), entity.save(), entity.delete()
  • Automatic context management
  • Support for JSON, SQLite, MongoDB, and DynamoDB backends
  • Multi-database support with prime database for core persistence
  • Custom database registration for extensibility
  • Pagination with ObjectPager

☁️ Serverless Deployment (AWS Lambda)

  • Zero-configuration Lambda deployment with LambdaServer
  • Automatic Mangum integration for FastAPI → Lambda compatibility
  • Native DynamoDB support for persistent storage in serverless environments
  • Handler automatically exposed at module level for Lambda
  • Works seamlessly with API Gateway
  • See Lambda Example for complete deployment guide

⚙️ Unified Configuration

  • Single Config class for all settings
  • Environment variable support
  • Type-safe configuration

🚀 FastAPI Integration

  • Built-in FastAPI server with automatic OpenAPI documentation
  • Automatic endpoint registration from decorators
  • Authentication and authorization with automatic endpoint registration when enabled
  • Response schema definitions with examples
  • Entity-centric CRUD operations
  • Serverless deployment to AWS Lambda with automatic handler setup

Installation

# Core installation
pip install jvspatial

# With serverless support (AWS Lambda + DynamoDB)
pip install jvspatial[serverless]

Quick Start

💡 Standard Examples: For production-ready API implementations, see:

Basic Example

from jvspatial.api import Server, endpoint
from jvspatial.core import Node

# Create server (entity-centric operations available automatically)
server = Server(
    title="My API",
    db_type="json",
    db_path="./jvdb",
    auth_enabled=False  # Set to True to enable authentication
)

# Define entity
class User(Node):
    name: str = ""
    email: str = ""

# Create endpoint
@endpoint("/users/{user_id}", methods=["GET"])
async def get_user(user_id: str):
    user = await User.get(user_id)
    if not user:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="User not found")
    return {"user": await user.export()}

if __name__ == "__main__":
    server.run()

Serverless Deployment (AWS Lambda)

Deploy to AWS Lambda with zero configuration changes:

from jvspatial.api import endpoint
from jvspatial.api.lambda_server import LambdaServer
from jvspatial.core import Node

# Use LambdaServer for Lambda deployments - handler is automatically created and exposed
# DynamoDB is the default database (can be overridden)
server = LambdaServer(
    title="Lambda API",
    dynamodb_table_name="myapp",
    dynamodb_region="us-east-1",
)

class Product(Node):
    name: str = ""
    price: float = 0.0

@endpoint("/products", methods=["GET"])
async def list_products():
    products = await Product.find({})
    import asyncio
    products_list = await asyncio.gather(*[p.export() for p in products])
    return {"products": products_list}

# Handler is automatically available at module level for Lambda
# No manual assignment needed! AWS Lambda will call: lambda_example.handler

Deployment Steps:

  1. Install: pip install jvspatial[serverless]
  2. Package your code and dependencies
  3. Set Lambda handler to: your_module.handler
  4. Configure API Gateway trigger
  5. Deploy!

See the complete Lambda example for full deployment guide.

Core Concepts

Entity Definition and Attributes

from jvspatial.core import Node
from jvspatial.core.annotations import attribute

class User(Node):
    name: str = ""
    email: str = ""
    cache: dict = attribute(transient=True, default_factory=dict)

Unified Endpoint Decorator

The @endpoint decorator works with both functions and Walker classes:

from jvspatial.api import Server, endpoint
from jvspatial.core import Node

server = Server(title="My API", db_type="json", db_path="./jvdb")

# Function endpoint
@endpoint("/api/users", methods=["GET"])
async def list_users(page: int = 1, per_page: int = 10):
    from jvspatial.core.pager import ObjectPager
    pager = ObjectPager(User, page_size=per_page)
    users = await pager.get_page(page=page)
    import asyncio
    users_list = await asyncio.gather(*[user.export() for user in users])
    return {"users": users_list}

# Authenticated endpoint
@endpoint("/api/admin", methods=["GET"], auth=True, roles=["admin"])
async def admin_panel():
    return {"admin": "dashboard"}

# Endpoint with response schema
from jvspatial.api.endpoints.response import ResponseField, success_response

@endpoint(
    "/api/users",
    methods=["GET"],
    response=success_response(
        data={
            "users": ResponseField(List[Dict], "List of users"),
            "total": ResponseField(int, "Total count")
        }
    )
)
async def get_users():
    return {"users": [], "total": 0}

Entity-Centric Database Operations

from jvspatial.core import Node

class User(Node):
    name: str = ""
    email: str = ""

# Entity-centric operations (no context needed - server provides it automatically)
user = await User.create(name="John", email="john@example.com")
users = await User.find({"context.name": "John"})  # Use context. prefix for fields
user = await User.get(user_id)  # Returns None if not found
if user:
    await user.save()
    await user.delete()

# Efficient counting
total_users = await User.count()  # Count all users
active_users = await User.count({"context.active": True})  # Count filtered users using query dict
active_users = await User.count(active=True)  # Count filtered users using keyword arguments

Configuration

Server Configuration

from jvspatial.api import Server

# Basic server
server = Server(
    title="My API",
    description="API description",
    version="1.0.0",
    db_type="json",
    db_path="./jvdb"
)

# Server with authentication
server = Server(
    title="Secure API",
    auth_enabled=True,  # Automatically registers /auth/register, /auth/login, /auth/logout
    jwt_auth_enabled=True,
    jwt_secret="your-secret-key",
    jwt_expire_minutes=60,
    db_type="json",
    db_path="./jvdb"
)

# Server without authentication (public API)
server = Server(
    title="Public API",
    auth_enabled=False,  # NO authentication endpoints registered
    db_type="json",
    db_path="./jvdb_public"
)

Authentication Behavior

  • auth_enabled=True: Server automatically registers authentication endpoints (/auth/register, /auth/login, /auth/logout)
  • auth_enabled=False: Authentication endpoints are NOT registered (public API)

Documentation

Getting Started

API Development

Advanced Topics

Contributors

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

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

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

jvspatial-0.0.2.tar.gz (730.4 kB view details)

Uploaded Source

Built Distribution

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

jvspatial-0.0.2-py3-none-any.whl (310.4 kB view details)

Uploaded Python 3

File details

Details for the file jvspatial-0.0.2.tar.gz.

File metadata

  • Download URL: jvspatial-0.0.2.tar.gz
  • Upload date:
  • Size: 730.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for jvspatial-0.0.2.tar.gz
Algorithm Hash digest
SHA256 de292dde88b15d6a2251906620947f1bcba293c71057622a73ac8d969daadd03
MD5 cc7a7ecd7627b9dc36f0cd371c6dddc1
BLAKE2b-256 b7178f9febe30df26db3a1eb18d4dd6eaa1cbc103ce5a1a8fd7c5856c2a0f946

See more details on using hashes here.

File details

Details for the file jvspatial-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: jvspatial-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 310.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for jvspatial-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 542f9facfc17948ec8ac4c621b84db61ecea8f1cd1a397ce82a7f3d5cbfba303
MD5 0f0f3c3c7caa5f8f29c818d1eea3be85
BLAKE2b-256 c1eb32a9fe60058c2bab3d97a80e14cac637b3566a03cc30c7096c739dbcf0aa

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