📚 Complete API Documentation Created

Files Generated:

  1. API_ENDPOINTS.md (1,171 lines)
    - Complete documentation of all 771 DocTypes in ERPNext
    - Organized by 37 modules
    - Sample record names for each DocType
    - Full REST endpoint patterns
    - Examples and usage instructions
  2. generate_api_docs.py
    - Python script to auto-discover and document all API endpoints
    - Fetches live data from your ERPNext instance
    - Can be re-run anytime to update documentation
  3. discover_api_endpoints.sh
    - Bash alternative for API discovery
    - Lightweight script for quick checks
  4. test_api.sh
    - Ready-to-use API testing script
    - Demonstrates authentication and common API calls

  Key Features of the Documentation:

  Complete Coverage:

  -  All 771 DocTypes documented
  -  37 modules categorized
  -  Sample data for each DocType
  -  Single vs Standard vs Submittable types identified
  -  Child tables marked

  API Endpoint Patterns for Each DocType:

  # Standard DocTypes (e.g., Item, Customer)
  GET    /api/resource/{DocType}          # List all
  GET    /api/resource/{DocType}/{name}   # Get single
  POST   /api/resource/{DocType}          # Create new
  PUT    /api/resource/{DocType}/{name}   # Update
  DELETE /api/resource/{DocType}/{name}   # Delete

  # Single DocTypes (e.g., System Settings)
  GET    /api/resource/{DocType}/{DocType}  # Get singleton

  Sample DocTypes by Category:

  Standard DocTypes (most common):
  - Customer, Item, Sales Order, Purchase Order, etc.

  Single DocTypes (singletons):
  - System Settings, Accounts Settings, Stock Settings, etc.

  Submittable DocTypes (workflow):
  - Sales Invoice, Purchase Invoice, Journal Entry, etc.

  Child Tables (part of parent):
  - Sales Order Item, Purchase Order Item, etc.
This commit is contained in:
Brian Tan Seng 2025-08-22 17:23:16 +08:00
parent 44a463d99c
commit afe596e5ef
7 changed files with 2057 additions and 0 deletions

1171
API_ENDPOINTS.md Normal file

File diff suppressed because it is too large Load Diff

297
API_GUIDE.md Normal file
View File

@ -0,0 +1,297 @@
# ERPNext API Access Guide
## Overview
ERPNext provides comprehensive REST APIs for all its modules. The APIs follow RESTful conventions and return JSON responses.
**Important**: There is no browsable API index page at `/api/`. You must access specific endpoints directly.
## API Endpoints
### Base URL
```
http://localhost:8080
```
### Common API Endpoints
#### 1. **Authentication**
```bash
# Login
POST http://localhost:8080/api/method/login
{
"usr": "Administrator",
"pwd": "LocalDev123!"
}
```
#### 2. **Resource APIs**
All DocTypes (database tables) in ERPNext are accessible via REST:
```bash
# Get list of items
GET http://localhost:8080/api/resource/Item
# Get specific item
GET http://localhost:8080/api/resource/Item/{item_name}
# Create new item
POST http://localhost:8080/api/resource/Item
# Update item
PUT http://localhost:8080/api/resource/Item/{item_name}
# Delete item
DELETE http://localhost:8080/api/resource/Item/{item_name}
```
#### 3. **Method APIs**
Custom server methods can be called:
```bash
POST http://localhost:8080/api/method/{method_path}
```
## Authentication Methods
### 1. **Session-based Authentication**
After login, a session cookie is set which is used for subsequent requests.
### 2. **Token-based Authentication**
Generate API keys from the user settings:
1. Login to ERPNext UI
2. Go to Settings → My Settings
3. Scroll to "API Access" section
4. Generate API Secret
5. Use in requests:
```bash
curl -H "Authorization: token api_key:api_secret" \
http://localhost:8080/api/resource/Item
```
### 3. **Basic Authentication**
```bash
curl -u Administrator:LocalDev123! \
http://localhost:8080/api/resource/Item
```
## Live API Documentation
### 1. **Exploring Available DocTypes**
Get a list of all available DocTypes (tables/resources):
```bash
# After login
curl -b cookies.txt http://localhost:8080/api/resource/DocType
```
### 2. **Swagger/OpenAPI Documentation**
While ERPNext doesn't have built-in Swagger, you can explore APIs through:
- **Frappe Web UI**: After logging in, press `Ctrl+G` (or `Cmd+G` on Mac) to open the awesome bar and type any DocType name
- **Developer Console**: Access via browser DevTools to see API calls made by the UI
### 3. **Interactive Console**
Access the Python console to explore APIs:
```bash
# Enter the backend container
docker exec -it erpnext /bin/bash
# Start bench console
bench --site frontend console
# Example commands in console:
>>> frappe.get_all('Item')
>>> frappe.get_doc('Item', 'ITEM-001')
```
## Common API Operations
### Customer Management
```bash
# List customers
GET /api/resource/Customer
# Create customer
POST /api/resource/Customer
{
"customer_name": "Test Customer",
"customer_type": "Company",
"customer_group": "All Customer Groups",
"territory": "All Territories"
}
```
### Item Management
```bash
# List items
GET /api/resource/Item
# Create item
POST /api/resource/Item
{
"item_code": "TEST-001",
"item_name": "Test Item",
"item_group": "All Item Groups",
"stock_uom": "Nos"
}
```
### Sales Order
```bash
# Create sales order
POST /api/resource/Sales%20Order
{
"customer": "Test Customer",
"delivery_date": "2024-12-31",
"items": [
{
"item_code": "TEST-001",
"qty": 10,
"rate": 100
}
]
}
```
## API Response Format
### Success Response
```json
{
"data": {
// Response data
}
}
```
### Error Response
```json
{
"exc_type": "ValidationError",
"exception": "Error details",
"_server_messages": "..."
}
```
## Testing APIs
### Using cURL
```bash
# Login and save cookies
curl -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"usr":"Administrator","pwd":"LocalDev123!"}' \
http://localhost:8080/api/method/login
# Use cookies for subsequent requests
curl -b cookies.txt \
http://localhost:8080/api/resource/Item
```
### Using Postman
1. Import ERPNext collection (create your own based on endpoints above)
2. Set base URL to `http://localhost:8080`
3. Configure authentication in collection settings
### Using Python
```python
import requests
# Login
session = requests.Session()
login_response = session.post(
'http://localhost:8080/api/method/login',
json={'usr': 'Administrator', 'pwd': 'LocalDev123!'}
)
# Get items
items = session.get('http://localhost:8080/api/resource/Item')
print(items.json())
```
## Advanced Features
### 1. **Filters**
```bash
# Filter with conditions
GET /api/resource/Item?filters=[["item_group","=","Products"]]
# Multiple filters
GET /api/resource/Item?filters=[["item_group","=","Products"],["disabled","=",0]]
```
### 2. **Field Selection**
```bash
# Select specific fields
GET /api/resource/Item?fields=["item_code","item_name","standard_rate"]
```
### 3. **Pagination**
```bash
# Limit and offset
GET /api/resource/Item?limit_start=0&limit_page_length=20
```
### 4. **Sorting**
```bash
# Order by field
GET /api/resource/Item?order_by=modified%20desc
```
## WebSocket API
ERPNext also provides WebSocket connections for real-time updates:
```javascript
// Connect to WebSocket
const socket = io('http://localhost:8080', {
withCredentials: true
});
// Listen for events
socket.on('connect', () => {
console.log('Connected to ERPNext WebSocket');
});
```
## Rate Limiting
ERPNext implements rate limiting for API calls:
- Default: 60 requests per minute per IP
- Can be configured in site_config.json
## Security Best Practices
1. **Always use HTTPS in production**
2. **Generate and use API tokens instead of passwords**
3. **Implement IP whitelisting for API access**
4. **Regular token rotation**
5. **Monitor API usage logs**
## Debugging
### Enable Debug Mode
```bash
# In the backend container
bench --site frontend set-config developer_mode 1
bench --site frontend clear-cache
```
### View API Logs
```bash
# Check frappe logs
docker exec -it erpnext tail -f sites/frontend/logs/frappe.log
```
## References
- [Frappe REST API Documentation](https://frappeframework.com/docs/user/en/api/rest)
- [ERPNext API Reference](https://docs.erpnext.com/docs/user/manual/en/api)
- [Frappe Client Scripts](https://frappeframework.com/docs/user/en/desk/scripting/client-script)
## Need Help?
- Check the logs: `docker compose logs -f backend`
- Access the console: `docker exec -it erpnext bench --site frontend console`
- Visit the [ERPNext Forum](https://discuss.erpnext.com/) for community support

View File

@ -114,6 +114,31 @@ When changing `APP_VERSION` in `.env`:
- **Network**: All services communicate through the `erpnext-local` Docker network
- **Default Credentials**: Administrator / LocalDev123!
## API Development
### Accessing APIs
ERPNext provides REST APIs accessible at `http://localhost:8080/api/`
### Common API Endpoints
- **Login**: `POST /api/method/login`
- **Resources**: `/api/resource/{DocType}`
- **Methods**: `/api/method/{method_path}`
### Testing APIs
```bash
# Login and get session
curl -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"usr":"Administrator","pwd":"LocalDev123!"}' \
http://localhost:8080/api/method/login
# Use session for API calls
curl -b cookies.txt http://localhost:8080/api/resource/Item
```
### API Documentation
See [API_GUIDE.md](API_GUIDE.md) for comprehensive API documentation.
## Troubleshooting
### Port Conflicts

View File

@ -165,10 +165,21 @@ This deployment uses a microservices architecture with the following containers:
- **configurator**: Initial configuration (runs once)
- **create-site**: Site creation (runs once)
## API Access
ERPNext provides comprehensive REST APIs for integration. See [API_GUIDE.md](API_GUIDE.md) for detailed documentation on:
- Authentication methods
- REST API endpoints
- WebSocket connections
- API testing examples
Quick access: `http://localhost:8080/api/`
## Documentation
- [ERPNext Documentation](https://docs.erpnext.com/)
- [Frappe Framework Documentation](https://frappeframework.com/docs)
- [Frappe REST API Documentation](https://frappeframework.com/docs/user/en/api/rest)
- [Docker Compose Documentation](https://docs.docker.com/compose/)
## Contributing

190
discover_api_endpoints.sh Executable file
View File

@ -0,0 +1,190 @@
#!/bin/bash
# ERPNext API Discovery Script
# This script discovers all available DocTypes and their endpoints
API_URL="http://localhost:8080"
USERNAME="Administrator"
PASSWORD="LocalDev123!"
OUTPUT_FILE="API_ENDPOINTS.md"
echo "======================================"
echo "ERPNext API Discovery Script"
echo "======================================"
echo ""
# Login
echo "Logging in..."
curl -s -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d "{\"usr\":\"$USERNAME\",\"pwd\":\"$PASSWORD\"}" \
$API_URL/api/method/login > /dev/null
# Get all DocTypes
echo "Fetching all DocTypes..."
ALL_DOCTYPES=$(curl -s -b cookies.txt "$API_URL/api/resource/DocType?limit_page_length=1000&fields=\[\"name\",\"module\",\"is_submittable\",\"issingle\"\]" | jq -r '.data')
# Start creating the documentation
cat > $OUTPUT_FILE << 'EOF'
# ERPNext API Endpoints Documentation
Generated on: $(date)
This document provides a comprehensive list of all available API endpoints in ERPNext.
## Authentication
All API calls require authentication. First, login to get a session:
```bash
curl -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"usr":"Administrator","pwd":"your_password"}' \
http://localhost:8080/api/method/login
```
## API Endpoint Pattern
All DocTypes follow the same RESTful pattern:
- **List/Search**: `GET /api/resource/{DocType}`
- **Get Single**: `GET /api/resource/{DocType}/{name}`
- **Create**: `POST /api/resource/{DocType}`
- **Update**: `PUT /api/resource/{DocType}/{name}`
- **Delete**: `DELETE /api/resource/{DocType}/{name}`
## Available DocTypes and Endpoints
EOF
echo "" >> $OUTPUT_FILE
echo "Processing DocTypes and getting sample data..."
# Process each module
MODULES=$(echo "$ALL_DOCTYPES" | jq -r '.[].module' | sort -u)
for MODULE in $MODULES; do
echo "Processing module: $MODULE"
echo "" >> $OUTPUT_FILE
echo "### Module: $MODULE" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE
echo "| DocType | Single/List | Sample Names | Endpoints |" >> $OUTPUT_FILE
echo "|---------|-------------|--------------|-----------|" >> $OUTPUT_FILE
# Get DocTypes for this module
MODULE_DOCTYPES=$(echo "$ALL_DOCTYPES" | jq -r ".[] | select(.module==\"$MODULE\") | .name")
for DOCTYPE in $MODULE_DOCTYPES; do
# URL encode the DocType name
DOCTYPE_ENCODED=$(echo "$DOCTYPE" | sed 's/ /%20/g')
# Check if it's a single DocType
IS_SINGLE=$(echo "$ALL_DOCTYPES" | jq -r ".[] | select(.name==\"$DOCTYPE\") | .issingle")
# Get sample records (limit to 3)
SAMPLE_RECORDS=$(curl -s -b cookies.txt "$API_URL/api/resource/$DOCTYPE_ENCODED?limit_page_length=3&fields=\[\"name\"\]" 2>/dev/null | jq -r '.data[]?.name' 2>/dev/null | tr '\n' ', ' | sed 's/,$//' | sed 's/,/, /g')
if [ "$IS_SINGLE" == "1" ]; then
TYPE="Single"
ENDPOINTS="\`GET /api/resource/$DOCTYPE/$DOCTYPE\`"
SAMPLE_RECORDS="$DOCTYPE"
else
TYPE="List"
ENDPOINTS="\`/api/resource/$DOCTYPE\`"
if [ -z "$SAMPLE_RECORDS" ]; then
SAMPLE_RECORDS="No records"
fi
fi
# Escape pipe characters in sample records
SAMPLE_RECORDS=$(echo "$SAMPLE_RECORDS" | sed 's/|/\\|/g')
# Truncate if too long
if [ ${#SAMPLE_RECORDS} -gt 50 ]; then
SAMPLE_RECORDS="${SAMPLE_RECORDS:0:47}..."
fi
echo "| $DOCTYPE | $TYPE | $SAMPLE_RECORDS | $ENDPOINTS |" >> $OUTPUT_FILE
done
done
# Add common query parameters section
cat >> $OUTPUT_FILE << 'EOF'
## Common Query Parameters
### For List Endpoints
| Parameter | Description | Example |
|-----------|-------------|---------|
| `fields` | Select specific fields | `fields=["name","status"]` |
| `filters` | Filter results | `filters=[["status","=","Active"]]` |
| `limit_start` | Pagination offset | `limit_start=0` |
| `limit_page_length` | Page size | `limit_page_length=20` |
| `order_by` | Sort results | `order_by=modified desc` |
### Examples
#### Get list with filters
```bash
curl -b cookies.txt \
"http://localhost:8080/api/resource/Item?filters=[[\"item_group\",\"=\",\"Products\"]]&fields=[\"item_code\",\"item_name\"]"
```
#### Get single document
```bash
curl -b cookies.txt \
"http://localhost:8080/api/resource/User/Administrator"
```
#### Create new document
```bash
curl -b cookies.txt -X POST \
-H "Content-Type: application/json" \
-d '{"doctype":"Item","item_code":"TEST-001","item_name":"Test Item","item_group":"Products","stock_uom":"Nos"}' \
"http://localhost:8080/api/resource/Item"
```
#### Update document
```bash
curl -b cookies.txt -X PUT \
-H "Content-Type: application/json" \
-d '{"item_name":"Updated Test Item"}' \
"http://localhost:8080/api/resource/Item/TEST-001"
```
#### Delete document
```bash
curl -b cookies.txt -X DELETE \
"http://localhost:8080/api/resource/Item/TEST-001"
```
## Special Endpoints
### Authentication
- `POST /api/method/login` - Login
- `POST /api/method/logout` - Logout
### File Upload
- `POST /api/method/upload_file` - Upload files
### Reports
- `GET /api/method/frappe.desk.query_report.run` - Run reports
## Notes
1. **Single DocTypes**: These DocTypes have only one record (like System Settings) and use their name directly in the URL
2. **URL Encoding**: DocType names with spaces must be URL encoded (e.g., "Sales Order" becomes "Sales%20Order")
3. **Permissions**: Access to DocTypes depends on user permissions
4. **Rate Limiting**: Default rate limit is 60 requests per minute
EOF
echo ""
echo "======================================"
echo "Discovery complete!"
echo "Documentation saved to: $OUTPUT_FILE"
echo "======================================"
# Clean up
rm -f cookies.txt

319
generate_api_docs.py Executable file
View File

@ -0,0 +1,319 @@
#!/usr/bin/env python3
import requests
import json
from datetime import datetime
import urllib.parse
# Configuration
API_URL = "http://localhost:8080"
USERNAME = "Administrator"
PASSWORD = "LocalDev123!"
def login():
"""Login and return session"""
session = requests.Session()
response = session.post(
f"{API_URL}/api/method/login",
json={"usr": USERNAME, "pwd": PASSWORD}
)
if response.status_code == 200:
print("✓ Logged in successfully")
return session
else:
print("✗ Login failed")
return None
def get_all_doctypes(session):
"""Fetch all DocTypes"""
response = session.get(
f"{API_URL}/api/resource/DocType",
params={
"limit_page_length": 1000,
"fields": json.dumps(["name", "module", "issingle", "is_submittable", "istable"])
}
)
if response.status_code == 200:
return response.json().get("data", [])
return []
def get_sample_records(session, doctype, limit=3):
"""Get sample record names for a DocType"""
try:
# URL encode the DocType name
doctype_encoded = urllib.parse.quote(doctype)
response = session.get(
f"{API_URL}/api/resource/{doctype_encoded}",
params={
"limit_page_length": limit,
"fields": json.dumps(["name"])
}
)
if response.status_code == 200:
data = response.json().get("data", [])
return [record.get("name", "") for record in data]
except:
pass
return []
def generate_documentation(session):
"""Generate comprehensive API documentation"""
print("Fetching all DocTypes...")
doctypes = get_all_doctypes(session)
print(f"Found {len(doctypes)} DocTypes")
# Group by module
modules = {}
for doctype in doctypes:
module = doctype.get("module", "Unknown")
if module not in modules:
modules[module] = []
modules[module].append(doctype)
# Sort modules
sorted_modules = sorted(modules.keys())
# Generate markdown
doc = []
doc.append("# ERPNext API Endpoints Documentation")
doc.append("")
doc.append(f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
doc.append("")
doc.append("This document provides a comprehensive list of all available API endpoints in ERPNext.")
doc.append("")
# Authentication section
doc.append("## Authentication")
doc.append("")
doc.append("All API calls require authentication. First, login to get a session:")
doc.append("")
doc.append("```bash")
doc.append("curl -c cookies.txt -X POST \\")
doc.append(" -H \"Content-Type: application/json\" \\")
doc.append(" -d '{\"usr\":\"Administrator\",\"pwd\":\"your_password\"}' \\")
doc.append(" http://localhost:8080/api/method/login")
doc.append("```")
doc.append("")
# API Pattern section
doc.append("## API Endpoint Pattern")
doc.append("")
doc.append("All DocTypes follow the same RESTful pattern:")
doc.append("")
doc.append("- **List/Search**: `GET /api/resource/{DocType}`")
doc.append("- **Get Single**: `GET /api/resource/{DocType}/{name}`")
doc.append("- **Create**: `POST /api/resource/{DocType}`")
doc.append("- **Update**: `PUT /api/resource/{DocType}/{name}`")
doc.append("- **Delete**: `DELETE /api/resource/{DocType}/{name}`")
doc.append("")
# Table of Contents
doc.append("## Table of Contents")
doc.append("")
for module in sorted_modules:
doc.append(f"- [{module}](#{module.lower().replace(' ', '-')})")
doc.append("")
# DocTypes by Module
doc.append("## Available DocTypes by Module")
doc.append("")
total_processed = 0
for module in sorted_modules:
print(f"\nProcessing module: {module}")
doc.append(f"### {module}")
doc.append("")
doc.append("| DocType | Type | Sample Names | API Endpoints |")
doc.append("|---------|------|--------------|---------------|")
module_doctypes = sorted(modules[module], key=lambda x: x.get("name", ""))
for doctype_info in module_doctypes:
doctype = doctype_info.get("name", "")
issingle = doctype_info.get("issingle", 0)
istable = doctype_info.get("istable", 0)
is_submittable = doctype_info.get("is_submittable", 0)
# Determine type
if issingle:
dtype = "Single"
elif istable:
dtype = "Child Table"
elif is_submittable:
dtype = "Submittable"
else:
dtype = "Standard"
# Get sample records
if issingle:
samples = [doctype]
elif istable:
samples = ["(Child of parent doc)"]
else:
samples = get_sample_records(session, doctype)
if not samples:
samples = ["(No records)"]
# Format samples
sample_str = ", ".join(str(s) for s in samples[:2])
if len(sample_str) > 40:
sample_str = sample_str[:37] + "..."
# Format endpoints
doctype_url = urllib.parse.quote(doctype)
if issingle:
endpoints = f"`GET /api/resource/{doctype_url}/{doctype_url}`"
else:
endpoints = f"`/api/resource/{doctype_url}`"
doc.append(f"| {doctype} | {dtype} | {sample_str} | {endpoints} |")
total_processed += 1
if total_processed % 10 == 0:
print(f" Processed {total_processed} DocTypes...")
doc.append("")
print(f"\nProcessed {total_processed} DocTypes total")
# Common Query Parameters
doc.append("## Common Query Parameters")
doc.append("")
doc.append("### For List Endpoints")
doc.append("")
doc.append("| Parameter | Description | Example |")
doc.append("|-----------|-------------|---------|")
doc.append("| `fields` | Select specific fields | `fields=[\"name\",\"status\"]` |")
doc.append("| `filters` | Filter results | `filters=[[\"status\",\"=\",\"Active\"]]` |")
doc.append("| `limit_start` | Pagination offset | `limit_start=0` |")
doc.append("| `limit_page_length` | Page size | `limit_page_length=20` |")
doc.append("| `order_by` | Sort results | `order_by=modified desc` |")
doc.append("")
# Examples section
doc.append("## Examples")
doc.append("")
doc.append("### Get list with filters")
doc.append("```bash")
doc.append("curl -b cookies.txt \\")
doc.append(" \"http://localhost:8080/api/resource/Item?filters=[[\\\"item_group\\\",\\\"=\\\",\\\"Products\\\"]]&fields=[\\\"item_code\\\",\\\"item_name\\\"]\"")
doc.append("```")
doc.append("")
doc.append("### Get single document")
doc.append("```bash")
doc.append("curl -b cookies.txt \\")
doc.append(" \"http://localhost:8080/api/resource/User/Administrator\"")
doc.append("```")
doc.append("")
doc.append("### Create new document")
doc.append("```bash")
doc.append("curl -b cookies.txt -X POST \\")
doc.append(" -H \"Content-Type: application/json\" \\")
doc.append(" -d '{\"doctype\":\"Item\",\"item_code\":\"TEST-001\",\"item_name\":\"Test Item\",\"item_group\":\"Products\",\"stock_uom\":\"Nos\"}' \\")
doc.append(" \"http://localhost:8080/api/resource/Item\"")
doc.append("```")
doc.append("")
doc.append("### Update document")
doc.append("```bash")
doc.append("curl -b cookies.txt -X PUT \\")
doc.append(" -H \"Content-Type: application/json\" \\")
doc.append(" -d '{\"item_name\":\"Updated Test Item\"}' \\")
doc.append(" \"http://localhost:8080/api/resource/Item/TEST-001\"")
doc.append("```")
doc.append("")
doc.append("### Delete document")
doc.append("```bash")
doc.append("curl -b cookies.txt -X DELETE \\")
doc.append(" \"http://localhost:8080/api/resource/Item/TEST-001\"")
doc.append("```")
doc.append("")
# Special Endpoints
doc.append("## Special Endpoints")
doc.append("")
doc.append("### Authentication")
doc.append("- `POST /api/method/login` - Login")
doc.append("- `POST /api/method/logout` - Logout")
doc.append("")
doc.append("### File Operations")
doc.append("- `POST /api/method/upload_file` - Upload files")
doc.append("- `GET /api/method/download_file` - Download files")
doc.append("")
doc.append("### Reports")
doc.append("- `GET /api/method/frappe.desk.query_report.run` - Run reports")
doc.append("")
# DocType Categories
doc.append("## DocType Categories")
doc.append("")
doc.append("### Single DocTypes")
doc.append("These DocTypes have only one record (singleton pattern):")
doc.append("")
single_docs = [d.get("name") for d in doctypes if d.get("issingle")]
for doc_name in sorted(single_docs)[:20]: # Show first 20
doc.append(f"- {doc_name}")
if len(single_docs) > 20:
doc.append(f"- ... and {len(single_docs) - 20} more")
doc.append("")
doc.append("### Child Tables")
doc.append("These DocTypes are child tables and cannot be accessed directly:")
doc.append("")
child_docs = [d.get("name") for d in doctypes if d.get("istable")]
for doc_name in sorted(child_docs)[:20]: # Show first 20
doc.append(f"- {doc_name}")
if len(child_docs) > 20:
doc.append(f"- ... and {len(child_docs) - 20} more")
doc.append("")
doc.append("### Submittable DocTypes")
doc.append("These DocTypes support document submission workflow:")
doc.append("")
submit_docs = [d.get("name") for d in doctypes if d.get("is_submittable")]
for doc_name in sorted(submit_docs)[:20]: # Show first 20
doc.append(f"- {doc_name}")
if len(submit_docs) > 20:
doc.append(f"- ... and {len(submit_docs) - 20} more")
doc.append("")
# Notes
doc.append("## Important Notes")
doc.append("")
doc.append("1. **URL Encoding**: DocType names with spaces must be URL encoded (e.g., \"Sales Order\"\"Sales%20Order\")")
doc.append("2. **Permissions**: Access to DocTypes depends on user permissions")
doc.append("3. **Rate Limiting**: Default rate limit is 60 requests per minute")
doc.append("4. **Single DocTypes**: Use the DocType name as both the resource and document name")
doc.append("5. **Child Tables**: Cannot be accessed directly, only through their parent document")
doc.append("6. **Submittable Documents**: Support additional states (Draft, Submitted, Cancelled)")
doc.append("")
return "\n".join(doc)
def main():
print("=" * 50)
print("ERPNext API Documentation Generator")
print("=" * 50)
print()
# Login
session = login()
if not session:
print("Failed to login!")
return
# Generate documentation
documentation = generate_documentation(session)
# Save to file
output_file = "API_ENDPOINTS.md"
with open(output_file, "w") as f:
f.write(documentation)
print()
print("=" * 50)
print(f"✓ Documentation saved to: {output_file}")
print("=" * 50)
if __name__ == "__main__":
main()

44
test_api.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
# ERPNext API Test Script
# This script demonstrates how to access ERPNext APIs
API_URL="http://localhost:8080"
USERNAME="Administrator"
PASSWORD="LocalDev123!"
echo "======================================"
echo "ERPNext API Test Script"
echo "======================================"
echo ""
# 1. Login and save cookies
echo "1. Logging in..."
curl -s -c cookies.txt -X POST \
-H "Content-Type: application/json" \
-d "{\"usr\":\"$USERNAME\",\"pwd\":\"$PASSWORD\"}" \
$API_URL/api/method/login | jq '.'
echo ""
echo "2. Getting list of DocTypes (first 5)..."
curl -s -b cookies.txt "$API_URL/api/resource/DocType?limit_page_length=5" | jq '.data[].name'
echo ""
echo "3. Getting list of Users..."
curl -s -b cookies.txt "$API_URL/api/resource/User?fields=\[\"name\",\"full_name\",\"enabled\"\]&limit_page_length=3" | jq '.'
echo ""
echo "4. Getting system settings..."
curl -s -b cookies.txt "$API_URL/api/resource/System%20Settings/System%20Settings" | jq '{country: .data.country, timezone: .data.time_zone}'
echo ""
echo "5. Getting Company list..."
curl -s -b cookies.txt "$API_URL/api/resource/Company" | jq '.'
echo ""
echo "======================================"
echo "API test complete!"
echo "======================================"
# Clean up
rm -f cookies.txt