langtask


Namelangtask JSON
Version 0.1.2 PyPI version JSON
download
home_pageNone
SummaryA Python library for structured LLM development with schema validation
upload_time2024-12-18 00:20:06
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords llm prompt anthropic openai claude
VCS
bugtrack_url
requirements pyyaml python-dotenv pydantic langchain langchain_openai langchain_anthropic loguru
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 0.43572s