security(p0): set strong ADMIN_PASSWORD in .env and sync DB admin hash; remove hardcoded 'admin123' in example; update TODO

This commit is contained in:
HotSwapp
2025-08-17 22:32:02 -05:00
parent e93b6db64a
commit 321b0085c6
2 changed files with 269 additions and 1 deletions

View File

@@ -0,0 +1,268 @@
#!/usr/bin/env python3
"""
Advanced Template Features Example
This script demonstrates how to use the enhanced template system
with conditional sections, loops, and rich formatting.
"""
import asyncio
import httpx
import json
from datetime import date, datetime
class AdvancedTemplateExample:
def __init__(self, base_url="http://localhost:8000"):
self.base_url = base_url
self.auth_token = None
async def authenticate(self, username="admin", password=None):
"""Authenticate and get access token"""
async with httpx.AsyncClient() as client:
from os import getenv
if password is None:
password = getenv("ADMIN_PASSWORD", "")
response = await client.post(
f"{self.base_url}/api/auth/token",
data={"username": username, "password": password}
)
if response.status_code == 200:
self.auth_token = response.json()["access_token"]
print("✅ Authentication successful")
else:
print(f"❌ Authentication failed: {response.text}")
return False
return True
@property
def headers(self):
if not self.auth_token:
raise ValueError("Not authenticated")
return {"Authorization": f"Bearer {self.auth_token}"}
async def test_variable_formatting(self):
"""Test variable formatting without generating documents"""
print("\n📝 Testing Variable Formatting...")
test_cases = [
{"value": "1234.56", "format": "currency", "expected": "$1,234.56"},
{"value": "2023-12-25", "format": "date:%B %d, %Y", "expected": "December 25, 2023"},
{"value": "5551234567", "format": "phone", "expected": "(555) 123-4567"},
{"value": "hello world", "format": "title", "expected": "Hello World"},
{"value": "75.5", "format": "percentage:1", "expected": "75.5%"}
]
async with httpx.AsyncClient() as client:
for test in test_cases:
response = await client.post(
f"{self.base_url}/api/templates/test-formatting",
headers=self.headers,
data={
"variable_value": test["value"],
"format_spec": test["format"]
}
)
if response.status_code == 200:
result = response.json()
actual = result["formatted_result"]
status = "" if actual == test["expected"] else ""
print(f" {status} {test['value']} | {test['format']}{actual}")
else:
print(f" ❌ Error testing {test['format']}: {response.text}")
async def demonstrate_template_features(self):
"""Demonstrate advanced template features with sample data"""
print("\n🎯 Demonstrating Advanced Template Features...")
# Sample context data that would come from database
sample_context = {
"CLIENT_NAME": "Smith Family Trust",
"FILE_NO": "2023-1001",
"ATTORNEY": "Jane Doe, Esq.",
"TODAY": date.today().isoformat(),
"CLIENT_BALANCE": 2500.00,
"total_amount": 8750.00,
"payment_terms": "Net 30",
# Sample services for loop demonstration
"services": [
{
"description": "Estate Planning Consultation",
"date": "2023-11-15",
"hours": 2.5,
"rate": 350.00,
"amount": 875.00
},
{
"description": "Trust Document Preparation",
"date": "2023-11-20",
"hours": 6.0,
"rate": 350.00,
"amount": 2100.00
},
{
"description": "Document Review and Revision",
"date": "2023-11-25",
"hours": 3.5,
"rate": 350.00,
"amount": 1225.00
},
{
"description": "Client Meeting and Execution",
"date": "2023-11-30",
"hours": 2.0,
"rate": 350.00,
"amount": 700.00
}
],
# Sample payments for another loop
"payments": [
{"date": "2023-11-01", "amount": 1000.00, "method": "Check"},
{"date": "2023-11-15", "amount": 1500.00, "method": "Wire Transfer"}
]
}
print("Sample context data:")
print(json.dumps(sample_context, indent=2, default=str))
return sample_context
async def get_formatting_help(self):
"""Get and display formatting help"""
print("\n📚 Available Formatting Options...")
async with httpx.AsyncClient() as client:
response = await client.get(
f"{self.base_url}/api/templates/formatting-help",
headers=self.headers
)
if response.status_code == 200:
help_data = response.json()
print("\n🔧 Formatting Options:")
for category, info in help_data["formatting_options"].items():
print(f"\n {category.upper()}:")
print(f" Description: {info['description']}")
if 'syntax' in info:
print(f" Syntax: {info['syntax']}")
if 'examples' in info:
print(" Examples:")
for example in info['examples'][:2]: # Show first 2 examples
print(f" {example['input']} | {example['format']}{example['output']}")
print("\n📝 Template Syntax:")
for syntax_type, syntax in help_data["template_syntax"].items():
print(f" {syntax_type}: {syntax}")
else:
print(f"❌ Error getting help: {response.text}")
async def create_sample_template_content(self):
"""Generate sample template content for demonstration"""
template_content = """
LEGAL SERVICES INVOICE
Client: {{ CLIENT_NAME | title }}
File Number: {{ FILE_NO }}
Attorney: {{ ATTORNEY }}
Date: {{ TODAY | date }}
{% if CLIENT_BALANCE > 0 %}
NOTICE: Outstanding balance of {{ CLIENT_BALANCE | currency }}
{% endif %}
SERVICES PROVIDED:
{% for service in services %}
{{ service_index }}. {{ service.description }}
Date: {{ service.date | date:%m/%d/%Y }}
Hours: {{ service.hours | number:1 }}
Rate: {{ service.rate | currency }}
Amount: {{ service.amount | currency }}
{% endfor %}
SUBTOTAL: {{ format_currency(total_amount) }}
{% if payments %}
PAYMENTS RECEIVED:
{% for payment in payments %}
- {{ payment.date | date:%m/%d/%Y }}: {{ payment.amount | currency }} ({{ payment.method }})
{% endfor %}
{% endif %}
{% if payment_terms %}
PAYMENT TERMS: {{ payment_terms }}
{% else %}
Payment due within 30 days of invoice date.
{% endif %}
{% if CLIENT_BALANCE > 1000 %}
Please remit payment immediately to avoid service interruption.
{% else %}
Thank you for your prompt payment.
{% endif %}
Generated on {{ TODAY | date }} by the Delphi Database System
"""
print("\n📄 Sample Template Content:")
print("=" * 60)
print(template_content)
print("=" * 60)
return template_content
async def run_demonstration(self):
"""Run the complete demonstration"""
print("🚀 Advanced Template Features Demonstration")
print("=" * 50)
# Authenticate
if not await self.authenticate():
return
# Show available formatting options
await self.get_formatting_help()
# Test individual formatting functions
await self.test_variable_formatting()
# Show sample template and context
context = await self.demonstrate_template_features()
template_content = await self.create_sample_template_content()
print("\n✨ This demonstrates the following advanced features:")
print(" • Conditional sections ({% if %} blocks)")
print(" • Loop sections ({% for %} blocks)")
print(" • Variable formatting ({{ var | format }})")
print(" • Template functions ({{ format_currency() }})")
print(" • Rich context data with nested objects")
print("\n🔄 To use these features in your application:")
print(" 1. Create a DOCX template with the syntax above")
print(" 2. Upload it via /api/templates/upload")
print(" 3. Generate documents via /api/templates/{id}/generate-advanced")
print(" 4. Optionally convert to PDF by setting output_format: 'PDF'")
print("\n✅ Advanced template features are ready to use!")
async def main():
"""Main demonstration function"""
demo = AdvancedTemplateExample()
await demo.run_demonstration()
if __name__ == "__main__":
print("Advanced Template Features Example")
print("Make sure the Delphi Database server is running on http://localhost:8000")
print()
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\n👋 Demonstration interrupted")
except Exception as e:
print(f"\n❌ Error: {e}")