# LangTask
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
![Status](https://img.shields.io/badge/status-pre--alpha-red)
LangTask is a lightweight Python library for rapidly setting up and managing LLM prompts with structured input/output validation. It provides a clean, type-safe interface for working with language models while enforcing schema validation and proper error handling.
> ⚠️ **Development Status Note**: This is a work-in-progress personal project. The API will change significantly.
> 📝 **Documentation Note**: This project intentionally includes extensive documentation and inline examples to facilitate better understanding by LLMs. The API.md file can be used as a reference document in LLM chats to enable quick comprehension of the framework's usage patterns.
## Features
- 🔍 **Schema Validation**: Type-safe input and output validation using Pydantic models with dot notation access
- 🔄 **Provider Flexibility**: Support for multiple LLM providers (currently OpenAI and Anthropic)
- 📝 **Prompt Management**: Simple directory-based prompt organization and discovery
- ⚡ **Easy Integration**: Clean API for registering and running prompts
- 🛠️ **Error Handling**: Comprehensive error hierarchy with detailed feedback
- 📊 **Logging**: Structured logging with request tracing and performance monitoring
## Installation
```bash
pip install langtask
```
## Quick Start
First, import the library (we'll use this import in all following examples):
```python
import langtask as lt
```
1. Create a prompt directory structure:
```
prompts/
└── greeting/
├── config.yaml # LLM configuration
├── instructions.md # Prompt template
├── input_schema.yaml # Input validation schema
└── output_schema.yaml # Output validation schema (optional)
```
2. Configure your prompt:
```yaml
# config.yaml
id: greeting
display_name: Greeting Generator
description: Generates personalized greetings
llm:
provider: anthropic
model: claude-3-5-sonnet-20241022
temperature: 0.7
```
3. Define input schema:
```yaml
# input_schema.yaml
name:
type: string
description: Name of the person to greet
style:
type: string
description: Style of greeting
options: ["formal", "casual"]
required: false # This field is optional
```
4. Create prompt instructions:
```markdown
# Note: Variable names are case-insensitive
Generate a {{STYLE}} greeting for {{Name}}.
# Will work the same as:
Generate a {{style}} greeting for {{name}}.
```
5. Use in your code:
```python
# Register prompt directory
lt.register("prompts")
# For simple text responses (no output schema)
response = lt.run("greeting", {
"NAME": "Alice", # Will work
"style": "casual" # Will also work
})
print(response) # "Hey Alice! How's it going?"
# For structured responses (with output schema)
response = lt.run("analyze-sentiment", {
"text": "Great product!"
})
print(response.sentiment) # "positive"
print(response.confidence) # 0.95
print(response.word_count) # 2
```
## Variable Naming
LangTask handles variable names case-insensitively throughout the system:
- Template variables like `{{NAME}}`, `{{name}}`, or `{{Name}}` are treated as identical
- Input parameters can use any case (e.g., `"NAME"`, `"name"`, `"Name"`)
- Schema definitions use lowercase internally
- All comparisons and validations are case-insensitive
Type names in schemas should use JSON Schema conventions:
- Use `string` instead of `str`
- Use `integer` instead of `int`
- Use `number` instead of `float`
- Use `boolean` instead of `bool`
- Use `object` instead of `dict`
Arrays are defined using the `list` attribute on any field (e.g., `list: true`, `list: 3`, `list: "2-5"`, `list: "3+"`)
## Example Prompt Structure
LangTask uses a directory-based approach for organizing prompts:
```
prompts/
├── greeting/
│ ├── config.yaml
│ ├── instructions.md
│ └── input_schema.yaml
└── sentiment/
├── config.yaml
├── instructions.md
├── input_schema.yaml
└── output_schema.yaml
```
Each prompt requires:
- `config.yaml`: LLM provider settings and prompt metadata
- `instructions.md`: The actual prompt template with variable placeholders
- `input_schema.yaml`: Schema defining expected input parameters
- `output_schema.yaml`: Schema for structured output validation (required for dot notation access)
## Configuration
Set global defaults for all prompts:
```python
lt.set_global_config({
"provider": "anthropic",
"model": "claude-3-5-haiku-20241022",
"temperature": 0.1
})
```
Or use provider-specific settings per prompt in `config.yaml`:
```yaml
llm:
- provider: anthropic
model: claude-3-5-haiku-20241022
temperature: 0.7
- provider: openai
model: gpt-4
temperature: 0.5
max_tokens: 1000
```
## Structured Responses
When using output schemas, responses are returned as Pydantic models with dot notation access:
```yaml
# Define output schema (output_schema.yaml):
sentiment:
type: string
description: Detected sentiment
options: ["positive", "negative", "neutral"]
confidence:
type: number
description: Confidence score
required: false # Optional field
word_count:
type: integer
description: Number of words analyzed
```
> **Note**: The `options` field can be used with string, integer, and number types as long as all values are of the same type. For example:
```yaml
priority:
type: integer
options: [1, 2, 3]
confidence_intervals:
type: number
options: [0.25, 0.5, 0.75, 1.0]
```
```python
# Access in code:
result = lt.run("analyze-sentiment", {"text": "Great product!"})
# Access fields with dot notation
print(result.sentiment) # "positive"
print(result.confidence) # 0.95
print(f"Analysis based on {result.word_count} words")
# Convert to dictionary if needed
data = result.model_dump()
```
Key benefits:
- Type-safe field access
- IDE autocompletion support
- Immutable response objects
- Automatic type conversion
- Clear error messages for invalid access
## Logging
LangTask provides comprehensive logging with configurable settings for both console and file output:
### Features
- Colored console output with configurable level
- File logging with automatic rotation
- Request ID tracking for operation tracing
- Performance metrics for monitoring
- Structured formatting for easy parsing
### Configuration
Use `set_logs()` to configure logging behavior:
```python
# Basic usage - just set log directory
lt.set_logs("./my_logs")
# Detailed configuration
lt.set_logs(
path="./app/logs", # Custom log directory
console_level="WARNING", # Less console output
file_level="DEBUG", # Detailed file logs
rotation="100 MB", # Larger log files
retention="1 month" # Keep logs longer
)
# Reset to defaults (logs/ directory with standard settings)
lt.set_logs()
```
### Configuration Options
- `path`: Directory for log files (default: './logs')
- `console_level`: Console logging level (default: 'INFO')
- Options: 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'
- `file_level`: File logging level (default: 'DEBUG')
- Options: Same as console_level
- `rotation`: When to rotate log files (default: '10 MB')
- Size-based: '10 MB', '1 GB', etc.
- Time-based: '1 day', '1 week', etc.
- `retention`: How long to keep old logs (default: '1 week')
- '1 week', '1 month', '90 days', etc.
### Default Behavior
- Console: INFO level with color-coded output
- File: DEBUG level for detailed troubleshooting
- Location: `./logs/langtask.log`
- Rotation: 10 MB file size
- Retention: 1 week
### Fallback Behavior
If the specified log directory cannot be created or accessed:
- Custom path: Raises FileSystemError
- Default path: Falls back to console-only logging with warning
### Example Log Output
```
2024-03-22 10:15:30 | req-123 | INFO | prompt_loader | Loading prompt | prompt_id=greeting
2024-03-22 10:15:30 | req-123 | WARNING | schema_loader | Unknown field detected | field=custom_param
2024-03-22 10:15:31 | req-123 | SUCCESS | llm_processor | Request processed | duration_ms=523.45
```
## Environment Setup
LangTask supports multiple ways to configure your API keys:
1. Direct environment variables:
```bash
# For Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
# For OpenAI
export OPENAI_API_KEY=sk-...
```
2. Using `.env` file (recommended for development):
```bash
# .env
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
```
Then in your code:
```python
from dotenv import load_dotenv
load_dotenv()
```
3. Setting in your deployment environment (recommended for production)
Remember to add `.env` to your `.gitignore` to protect your API keys.
## Requirements
- Python 3.10 or higher
- Dependencies:
- pydantic >= 2.0
- langchain >= 0.1.0
- langchain-openai >= 0.0.2
- langchain-anthropic >= 0.1.1
- pyyaml >= 6.0
- python-dotenv >= 0.19.0
- loguru >= 0.7.0
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Feel free to submit an issue or pull request.
Raw data
{
"_id": null,
"home_page": null,
"name": "langtask",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "llm, prompt, anthropic, openai, claude",
"author": null,
"author_email": "Kamil Dembinski <kamiltdembinski@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/53/50/32a43857beccd151e48eb5eb18e82c4c9160c8b2c81515dfc45858dd9f8f/langtask-0.1.2.tar.gz",
"platform": null,
"description": "# LangTask\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)\n![Status](https://img.shields.io/badge/status-pre--alpha-red)\n\nLangTask is a lightweight Python library for rapidly setting up and managing LLM prompts with structured input/output validation. It provides a clean, type-safe interface for working with language models while enforcing schema validation and proper error handling.\n\n> \u26a0\ufe0f **Development Status Note**: This is a work-in-progress personal project. The API will change significantly.\n\n> \ud83d\udcdd **Documentation Note**: This project intentionally includes extensive documentation and inline examples to facilitate better understanding by LLMs. The API.md file can be used as a reference document in LLM chats to enable quick comprehension of the framework's usage patterns.\n\n\n## Features\n\n- \ud83d\udd0d **Schema Validation**: Type-safe input and output validation using Pydantic models with dot notation access\n- \ud83d\udd04 **Provider Flexibility**: Support for multiple LLM providers (currently OpenAI and Anthropic)\n- \ud83d\udcdd **Prompt Management**: Simple directory-based prompt organization and discovery\n- \u26a1 **Easy Integration**: Clean API for registering and running prompts\n- \ud83d\udee0\ufe0f **Error Handling**: Comprehensive error hierarchy with detailed feedback\n- \ud83d\udcca **Logging**: Structured logging with request tracing and performance monitoring\n\n## Installation\n\n```bash\npip install langtask\n```\n\n\n## Quick Start\n\nFirst, import the library (we'll use this import in all following examples):\n```python\nimport langtask as lt\n```\n\n1. Create a prompt directory structure:\n\n```\nprompts/\n\u2514\u2500\u2500 greeting/\n \u251c\u2500\u2500 config.yaml # LLM configuration\n \u251c\u2500\u2500 instructions.md # Prompt template\n \u251c\u2500\u2500 input_schema.yaml # Input validation schema\n \u2514\u2500\u2500 output_schema.yaml # Output validation schema (optional)\n```\n\n2. Configure your prompt:\n\n```yaml\n# config.yaml\nid: greeting\ndisplay_name: Greeting Generator\ndescription: Generates personalized greetings\nllm:\n provider: anthropic\n model: claude-3-5-sonnet-20241022\n temperature: 0.7\n```\n\n3. Define input schema:\n\n```yaml\n# input_schema.yaml\nname:\n type: string\n description: Name of the person to greet\nstyle:\n type: string\n description: Style of greeting\n options: [\"formal\", \"casual\"]\n required: false # This field is optional\n```\n\n4. Create prompt instructions:\n\n```markdown\n# Note: Variable names are case-insensitive\nGenerate a {{STYLE}} greeting for {{Name}}.\n# Will work the same as:\nGenerate a {{style}} greeting for {{name}}.\n```\n\n5. Use in your code:\n\n```python\n# Register prompt directory\nlt.register(\"prompts\")\n\n# For simple text responses (no output schema)\nresponse = lt.run(\"greeting\", {\n \"NAME\": \"Alice\", # Will work\n \"style\": \"casual\" # Will also work\n})\nprint(response) # \"Hey Alice! How's it going?\"\n\n# For structured responses (with output schema)\nresponse = lt.run(\"analyze-sentiment\", {\n \"text\": \"Great product!\"\n})\nprint(response.sentiment) # \"positive\"\nprint(response.confidence) # 0.95\nprint(response.word_count) # 2\n```\n\n\n## Variable Naming\n\nLangTask handles variable names case-insensitively throughout the system:\n- Template variables like `{{NAME}}`, `{{name}}`, or `{{Name}}` are treated as identical\n- Input parameters can use any case (e.g., `\"NAME\"`, `\"name\"`, `\"Name\"`)\n- Schema definitions use lowercase internally\n- All comparisons and validations are case-insensitive\n\nType names in schemas should use JSON Schema conventions:\n- Use `string` instead of `str`\n- Use `integer` instead of `int`\n- Use `number` instead of `float`\n- Use `boolean` instead of `bool`\n- Use `object` instead of `dict`\n\nArrays are defined using the `list` attribute on any field (e.g., `list: true`, `list: 3`, `list: \"2-5\"`, `list: \"3+\"`)\n\n\n## Example Prompt Structure\n\nLangTask uses a directory-based approach for organizing prompts:\n\n```\nprompts/\n\u251c\u2500\u2500 greeting/\n\u2502 \u251c\u2500\u2500 config.yaml\n\u2502 \u251c\u2500\u2500 instructions.md\n\u2502 \u2514\u2500\u2500 input_schema.yaml\n\u2514\u2500\u2500 sentiment/\n \u251c\u2500\u2500 config.yaml\n \u251c\u2500\u2500 instructions.md\n \u251c\u2500\u2500 input_schema.yaml\n \u2514\u2500\u2500 output_schema.yaml\n```\n\nEach prompt requires:\n- `config.yaml`: LLM provider settings and prompt metadata\n- `instructions.md`: The actual prompt template with variable placeholders\n- `input_schema.yaml`: Schema defining expected input parameters\n- `output_schema.yaml`: Schema for structured output validation (required for dot notation access)\n\n\n## Configuration\n\nSet global defaults for all prompts:\n\n```python\nlt.set_global_config({\n \"provider\": \"anthropic\",\n \"model\": \"claude-3-5-haiku-20241022\",\n \"temperature\": 0.1\n})\n```\n\nOr use provider-specific settings per prompt in `config.yaml`:\n\n```yaml\nllm:\n - provider: anthropic\n model: claude-3-5-haiku-20241022\n temperature: 0.7\n - provider: openai\n model: gpt-4\n temperature: 0.5\n max_tokens: 1000\n```\n\n\n## Structured Responses\n\nWhen using output schemas, responses are returned as Pydantic models with dot notation access:\n\n```yaml\n# Define output schema (output_schema.yaml):\nsentiment:\n type: string\n description: Detected sentiment\n options: [\"positive\", \"negative\", \"neutral\"]\nconfidence:\n type: number\n description: Confidence score\n required: false # Optional field\nword_count:\n type: integer\n description: Number of words analyzed\n```\n\n> **Note**: The `options` field can be used with string, integer, and number types as long as all values are of the same type. For example:\n```yaml\npriority:\n type: integer\n options: [1, 2, 3]\n \nconfidence_intervals:\n type: number\n options: [0.25, 0.5, 0.75, 1.0]\n```\n\n```python\n# Access in code:\nresult = lt.run(\"analyze-sentiment\", {\"text\": \"Great product!\"})\n\n# Access fields with dot notation\nprint(result.sentiment) # \"positive\"\nprint(result.confidence) # 0.95\nprint(f\"Analysis based on {result.word_count} words\")\n\n# Convert to dictionary if needed\ndata = result.model_dump()\n```\n\nKey benefits:\n- Type-safe field access\n- IDE autocompletion support\n- Immutable response objects\n- Automatic type conversion\n- Clear error messages for invalid access\n\n\n## Logging\n\nLangTask provides comprehensive logging with configurable settings for both console and file output:\n\n### Features\n- Colored console output with configurable level\n- File logging with automatic rotation\n- Request ID tracking for operation tracing\n- Performance metrics for monitoring\n- Structured formatting for easy parsing\n\n### Configuration\nUse `set_logs()` to configure logging behavior:\n\n```python\n# Basic usage - just set log directory\nlt.set_logs(\"./my_logs\")\n\n# Detailed configuration\nlt.set_logs(\n path=\"./app/logs\", # Custom log directory\n console_level=\"WARNING\", # Less console output\n file_level=\"DEBUG\", # Detailed file logs\n rotation=\"100 MB\", # Larger log files\n retention=\"1 month\" # Keep logs longer\n)\n\n# Reset to defaults (logs/ directory with standard settings)\nlt.set_logs()\n```\n\n### Configuration Options\n- `path`: Directory for log files (default: './logs')\n- `console_level`: Console logging level (default: 'INFO')\n - Options: 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'\n- `file_level`: File logging level (default: 'DEBUG')\n - Options: Same as console_level\n- `rotation`: When to rotate log files (default: '10 MB')\n - Size-based: '10 MB', '1 GB', etc.\n - Time-based: '1 day', '1 week', etc.\n- `retention`: How long to keep old logs (default: '1 week')\n - '1 week', '1 month', '90 days', etc.\n\n### Default Behavior\n- Console: INFO level with color-coded output\n- File: DEBUG level for detailed troubleshooting\n- Location: `./logs/langtask.log`\n- Rotation: 10 MB file size\n- Retention: 1 week\n\n### Fallback Behavior\nIf the specified log directory cannot be created or accessed:\n- Custom path: Raises FileSystemError\n- Default path: Falls back to console-only logging with warning\n\n### Example Log Output\n```\n2024-03-22 10:15:30 | req-123 | INFO | prompt_loader | Loading prompt | prompt_id=greeting\n2024-03-22 10:15:30 | req-123 | WARNING | schema_loader | Unknown field detected | field=custom_param\n2024-03-22 10:15:31 | req-123 | SUCCESS | llm_processor | Request processed | duration_ms=523.45\n```\n\n\n## Environment Setup\n\nLangTask supports multiple ways to configure your API keys:\n\n1. Direct environment variables:\n```bash\n# For Anthropic\nexport ANTHROPIC_API_KEY=sk-ant-...\n\n# For OpenAI\nexport OPENAI_API_KEY=sk-...\n```\n\n2. Using `.env` file (recommended for development):\n```bash\n# .env\nANTHROPIC_API_KEY=sk-ant-...\nOPENAI_API_KEY=sk-...\n```\n\nThen in your code:\n```python\nfrom dotenv import load_dotenv\nload_dotenv()\n```\n\n3. Setting in your deployment environment (recommended for production)\n\nRemember to add `.env` to your `.gitignore` to protect your API keys.\n\n\n## Requirements\n\n- Python 3.10 or higher\n- Dependencies:\n - pydantic >= 2.0\n - langchain >= 0.1.0\n - langchain-openai >= 0.0.2\n - langchain-anthropic >= 0.1.1\n - pyyaml >= 6.0\n - python-dotenv >= 0.19.0\n - loguru >= 0.7.0\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nContributions are welcome! Feel free to submit an issue or pull request.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python library for structured LLM development with schema validation",
"version": "0.1.2",
"project_urls": {
"Github": "https://github.com/AgeofIA/langtask"
},
"split_keywords": [
"llm",
" prompt",
" anthropic",
" openai",
" claude"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fc8bf329f80eb773f2abf20d4ecb95270732a637877db2a4669e8d6b6e095d0e",
"md5": "c46cd3b0a74eb1932da19703eda23ff5",
"sha256": "a7880170736b739bbe5ba8a13aa129a8a4cbad750fd5cb1a1a7c1a82de0b4c80"
},
"downloads": -1,
"filename": "langtask-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c46cd3b0a74eb1932da19703eda23ff5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 47349,
"upload_time": "2024-12-18T00:20:04",
"upload_time_iso_8601": "2024-12-18T00:20:04.524084Z",
"url": "https://files.pythonhosted.org/packages/fc/8b/f329f80eb773f2abf20d4ecb95270732a637877db2a4669e8d6b6e095d0e/langtask-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "535032a43857beccd151e48eb5eb18e82c4c9160c8b2c81515dfc45858dd9f8f",
"md5": "3aac3c5869559e45df79712b0ed2a38d",
"sha256": "d3ad68d55cf511fd8131fab7d21fd779fc6918745f911793ec82bd9945de01cf"
},
"downloads": -1,
"filename": "langtask-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "3aac3c5869559e45df79712b0ed2a38d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 42203,
"upload_time": "2024-12-18T00:20:06",
"upload_time_iso_8601": "2024-12-18T00:20:06.995463Z",
"url": "https://files.pythonhosted.org/packages/53/50/32a43857beccd151e48eb5eb18e82c4c9160c8b2c81515dfc45858dd9f8f/langtask-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-18 00:20:06",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AgeofIA",
"github_project": "langtask",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "pyyaml",
"specs": []
},
{
"name": "python-dotenv",
"specs": []
},
{
"name": "pydantic",
"specs": []
},
{
"name": "langchain",
"specs": []
},
{
"name": "langchain_openai",
"specs": []
},
{
"name": "langchain_anthropic",
"specs": []
},
{
"name": "loguru",
"specs": []
}
],
"lcname": "langtask"
}