diff --git a/CLI_PYPROJECT.toml b/CLI_PYPROJECT.toml new file mode 100644 index 0000000..e4ac10b --- /dev/null +++ b/CLI_PYPROJECT.toml @@ -0,0 +1,36 @@ +# This file shows what the future CLI-only package pyproject.toml would look like +# Once CLI is separated into its own package: highflame-cli +# This serves as a reference for the CLI package separation plan + +[tool.poetry] +name = "highflame-cli" +version = "2.0.0" +description = "Command-line interface for Highflame - LLM Gateway Management" +authors = ["Sharath Rajasekar "] +readme = "README.md" +license = "Apache-2.0" +homepage = "https://highflame.com" +repository = "https://github.com/highflame-ai/highflame-cli" +packages = [ + { include = "highflame_cli" }, +] + +[tool.poetry.scripts] +highflame-cli = "highflame_cli.cli:main" + +[tool.poetry.dependencies] +python = "^3.9" +highflame = "^2.0.0" +requests = "^2.32.3" + +[tool.poetry.group.dev.dependencies] +black = "24.3.0" +flake8 = "^7.3.0" +pre-commit = "^3.3.1" +pytest = "^8.3.5" +pytest-mock = "^3.10.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + diff --git a/Makefile b/Makefile index bc4e7c4..d082c77 100644 --- a/Makefile +++ b/Makefile @@ -30,4 +30,4 @@ install: poetry install install-wheel: - pip install dist/javelin_sdk-0.2.6-py3-none-any.whl --force-reinstall + pip install dist/highflame-*.whl --force-reinstall diff --git a/README.md b/README.md index a5ba781..16039e6 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,443 @@ [![Ask DeepWiki](https://deepwiki.com/badge.svg "DeepWiki Documentation")](https://deepwiki.com/getjavelin/javelin-python) -## Highflame: an Enterprise-Scale, Fast LLM Gateway/Edge +## Highflame: Enterprise-Scale LLM Gateway -This is the Python client package for Highflame. +This is the Python SDK for Highflame - an enterprise-scale, fast LLM gateway that provides unified access to multiple LLM providers with advanced routing, monitoring, and management capabilities. -For more information about Highflame, see https://highflame.com +**Package Name:** `highflame` (v2.0.0) +**Previous Package:** `javelin_sdk` -Highflame Documentation: https://docs.getjavelin.io +For more information about Highflame, see [https://highflame.com](https://highflame.com) -### Development +Highflame Documentation: [https://docs.highflame.ai/](https://docs.highflame.ai/) -For local development, Please change `version = "RELEASE_VERSION"` with any semantic version example : `version = "v0.1.10"` in `pyproject.toml` +--- -*Make sure that the file `pyproject.toml` reverted before commit back to main* +## Quick Start ### Installation +```bash +pip install highflame +``` + +### Basic Usage + +```python +from highflame import Highflame, Config +import os + +# Initialize client +config = Config(api_key=os.getenv("HIGHFLAME_API_KEY")) +client = Highflame(config) + +# Query a route +response = client.query_route( + route_name="my_route", + query_body={"messages": [{"role": "user", "content": "Hello!"}], "model": "gpt-4"} +) +``` + +--- + +## What Changed + +### Package & Import Changes + +**v1:** + +```python +from javelin_sdk import JavelinClient, JavelinConfig +``` + +**v2:** + +```python +from highflame import Highflame, Config +``` + +### Class Name Changes + +| v1 | v2 | +| -------------------- | ------------- | +| `JavelinClient` | `Highflame` | +| `JavelinConfig` | `Config` | +| `JavelinClientError` | `ClientError` | + +### Configuration Changes + +**Environment Variables:** +All environment variable names have changed from `JAVELIN_*` to `HIGHFLAME_*`: + +| v1 | v2 | +| ----------------------- | ------------------------- | +| `JAVELIN_API_KEY` | `HIGHFLAME_API_KEY` | +| `JAVELIN_VIRTUALAPIKEY` | `HIGHFLAME_VIRTUALAPIKEY` | +| `JAVELIN_BASE_URL` | `HIGHFLAME_BASE_URL` | + +**Configuration Fields:** + +- `javelin_api_key` → `api_key` +- `javelin_virtualapikey` → `virtual_api_key` +- Default `base_url`: `https://api-dev.javelin.live` → `https://api.highflame.app` + +**Example:** + +**v1:** + +```python +from javelin_sdk import JavelinConfig + +config = JavelinConfig(javelin_api_key="your-key") +``` + +**v2:** + +```python +from highflame import Config + +config = Config(api_key="your-key") +``` + +### HTTP Headers (Backward Compatible) + +v2 sends **both** old and new headers for backward compatibility during the transition period: + +| Header Type | v1 | v2 (Primary) | v2 (Backward Compat) | +| --------------- | ------------------------- | --------------------------- | ------------------------- | +| API Key | `x-javelin-apikey` | `x-highflame-apikey` | `x-javelin-apikey` | +| Virtual API Key | `x-javelin-virtualapikey` | `x-highflame-virtualapikey` | `x-javelin-virtualapikey` | +| Route | `x-javelin-route` | `x-highflame-route` | `x-javelin-route` | +| Model | `x-javelin-model` | `x-highflame-model` | `x-javelin-model` | +| Provider | `x-javelin-provider` | `x-highflame-provider` | `x-javelin-provider` | +| Account ID | `x-javelin-accountid` | `x-highflame-accountid` | `x-javelin-accountid` | +| User | `x-javelin-user` | `x-highflame-user` | `x-javelin-user` | +| User Role | `x-javelin-userrole` | `x-highflame-userrole` | `x-javelin-userrole` | + +**Note:** Both header formats are sent simultaneously to ensure compatibility with existing backends. + +### API Endpoint Changes + +| v1 | v2 | +| ------------------------------ | --------------------------- | +| `https://api-dev.javelin.live` | `https://api.highflame.app` | + +### Exception Handling + +**v1:** + +```python +from javelin_sdk.exceptions import ( + JavelinClientError, + GatewayNotFoundError, + RouteNotFoundError, + # ... etc +) +``` + +**v2:** + +```python +from highflame.exceptions import ( + ClientError, + GatewayNotFoundError, + RouteNotFoundError, + # ... etc +) +``` + +All exception classes now inherit from `ClientError` instead of `JavelinClientError`. + +### OpenTelemetry Tracing + +**Service & Tracer Names:** + +- Service name: `"javelin-sdk"` → `"highflame"` +- Tracer name: `"javelin"` → `"highflame"` + +**Span Attributes:** + +- `javelin.response.body` → `highflame.response.body` +- `javelin.error` → `highflame.error` + +### CLI Changes + +**Command Name:** + +- `javelin` → `highflame` + +**Cache Directory:** + +- `~/.javelin/` → `~/.highflame/` + +**Example:** + +**v1:** + +```bash +javelin auth +javelin routes list +``` + +**v2:** + +```bash +highflame-cli auth +highflame-cli route list +``` + +### Exception Handling Changes + +**v1:** + +```python +from javelin_sdk.exceptions import ( + JavelinClientError, + RouteNotFoundError, + ProviderNotFoundError, +) + +try: + client.query_route(...) +except JavelinClientError as e: + print(f"Error: {e}") +``` + +**v2:** + +```python +from highflame.exceptions import ( + ClientError, + RouteNotFoundError, + ProviderNotFoundError, +) + +try: + client.query_route(...) +except ClientError as e: + print(f"Error: {e}") +``` + +### Complete Migration Example + +**v1 Code:** + +```python +import os +from javelin_sdk import JavelinClient, JavelinConfig +from javelin_sdk.exceptions import RouteNotFoundError + +# Get API key from environment +api_key = os.getenv("JAVELIN_API_KEY") + +# Create configuration +config = JavelinConfig( + javelin_api_key=api_key, + base_url="https://api-dev.javelin.live" +) + +# Create client +client = JavelinClient(config) + +# Query a route +try: + response = client.query_route( + route_name="my_route", + query_body={ + "messages": [{"role": "user", "content": "Hello"}], + "model": "gpt-4" + } + ) + print(response) +except RouteNotFoundError as e: + print(f"Route not found: {e}") +finally: + client.close() +``` + +**v2 Code:** + +```python +import os +from highflame import Highflame, Config +from highflame.exceptions import RouteNotFoundError + +# Get API key from environment +api_key = os.getenv("HIGHFLAME_API_KEY") + +# Create configuration +config = Config( + api_key=api_key, + base_url="https://api.highflame.app" +) + +# Create client +client = Highflame(config) + +# Query a route +try: + response = client.query_route( + route_name="my_route", + query_body={ + "messages": [{"role": "user", "content": "Hello"}], + "model": "gpt-4" + } + ) + print(response) +except RouteNotFoundError as e: + print(f"Route not found: {e}") +finally: + client.close() +``` + +### Async/Await Support + +Async support remains unchanged in v2: + ```python - pip install javelin-sdk +async with Highflame(config) as client: + response = await client.aquery_route( + route_name="my_route", + query_body={...} + ) +``` + +### Migration Checklist + +1. ✅ Update package installation: `pip install highflame` (instead of `javelin_sdk` or `highflame-sdk`) +2. ✅ Update imports: `from highflame import Highflame, Config` +3. ✅ Update class names: `JavelinClient` → `Highflame`, `JavelinConfig` → `Config` +4. ✅ Update environment variables: `JAVELIN_*` → `HIGHFLAME_*` +5. ✅ Update configuration field names: `javelin_api_key` → `api_key` +6. ✅ Update API endpoint if using custom base URL +7. ✅ Update exception imports: `JavelinClientError` → `ClientError` +8. ✅ Update CLI commands: `javelin` → `highflame-cli` +9. ✅ Update cache directory references if any + +**Note:** HTTP headers are backward compatible - both old and new headers are sent automatically, so no immediate changes needed for header handling. The v2 SDK maintains **full API compatibility** with v1 in terms of functionality - all methods, parameters, and responses remain the same, only naming conventions have changed. + +--- + +## Backend Changes Required + +To complete the migration from Javelin to Highflame, the following backend changes are required: + +### 1. Database Schema Changes + +**File: `highflame-admin/internal/admin/module/keyvault/schema.go`** + +- Rename field: `JavelinSecretKey` → `HighflameSecretKey` +- Database column: `api_key_secret_key_javelin` → `api_key_secret_key_highflame` +- Database column: `api_key_secret_key_javelin_start` → `api_key_secret_key_highflame_start` + +**File: `highflame-admin/internal/admin/module/apikey/schema.go`** + +- Table name: `javelinapikeys` → `highflameapikeys` (or maintain backward compatibility) +- Struct name: `JavelinAPIKey` → `HighflameAPIKey` + +### 2. Go Model Changes + +**File: `highflame-admin/internal/admin/model/keyvault.go`** + +```go +// Change: +JavelinSecretKey string `json:"api_key_secret_key_javelin,omitempty"` + +// To: +HighflameSecretKey string `json:"api_key_secret_key_highflame,omitempty"` +``` + +**File: `highflame-admin/internal/admin/model/apikey.go`** + +```go +// Change: +type JavelinAPIKey struct { ... } + +// To: +type HighflameAPIKey struct { ... } +``` + +**File: `highflame-admin/internal/admin/model/chronicle.go`** + +```go +// Change: +JavelinResponseHeaders json.RawMessage `json:"javelin_response_headers"` + +// To: +HighflameResponseHeaders json.RawMessage `json:"highflame_response_headers"` ``` -### Quick Start Guide +### 3. Service Layer Changes + +**File: `highflame-admin/internal/admin/module/keyvault/service.go`** + +- Update all `JavelinSecretKey` references to `HighflameSecretKey` +- Update variable names: `javelin_key` → `highflame_key`, etc. + +**File: `highflame-admin/internal/admin/module/audit/repo.go`** + +- Update field deletion: `"api_key_secret_key_javelin"` → `"api_key_secret_key_highflame"` + +### 4. Swagger/OpenAPI Specification Updates + +**Files to update:** + +- `highflame-admin/docs/swagger.yaml` +- `highflame-admin/docs/swagger.json` +- `highflame-admin/docs/docs.go` + +**Changes required:** + +- `api_key_secret_key_javelin` → `api_key_secret_key_highflame` +- `javelin_response_headers` → `highflame_response_headers` +- Model names: `JavelinAPIKey` → `HighflameAPIKey` + +After updating, regenerate the Swagger spec and sync Python SDK models using `swagger/sync_models.py`. + +### 5. Database Migration + +Create a migration script to: + +1. Add new columns alongside old ones (for zero-downtime migration) +2. Migrate existing data from old columns to new columns +3. Update application code to use new field names +4. Deprecate old columns after transition period +5. Remove old columns in a future release + +### 6. Other Backend Services + +**File: `highflame-core/pkg/persist/admin_client/aws_secrets.go`** + +- Update `JavelinSecretKey` field to `HighflameSecretKey` + +**File: `highflame-core/tests/e2e/promptfoo/extensions/shared/utils.js`** + +- Update test references from `api_key_secret_key_javelin` to `api_key_secret_key_highflame` + +### 7. API Header Support (Backward Compatibility) + +The Python SDK currently sends both `x-javelin-*` and `x-highflame-*` headers for backward compatibility. The backend should: + +- **Continue accepting** `x-javelin-*` headers during the transition period +- **Prefer** `x-highflame-*` headers when both are present +- **Plan deprecation timeline** for old headers (recommend 6-12 month transition period) +- **Log usage** of old headers to track migration progress + +### Backend Migration Checklist + +- [ ] Database schema: Add new `api_key_secret_key_highflame` column +- [ ] Database migration: Script to migrate data from old to new columns +- [ ] Go models: Rename `JavelinSecretKey` → `HighflameSecretKey` +- [ ] Go structs: Rename `JavelinAPIKey` → `HighflameAPIKey` +- [ ] Service layer: Update all field references +- [ ] Swagger spec: Regenerate with new field names +- [ ] Tests: Update all test references +- [ ] Documentation: Update API documentation +- [ ] Header support: Ensure both old and new headers are accepted +- [ ] Monitoring: Track usage of old vs new headers/fields +- [ ] Deprecation plan: Create timeline for removing old fields/headers + +--- ## Development Setup @@ -58,51 +475,251 @@ poetry install ```bash # Uninstall any existing version -pip uninstall javelin-sdk -y +pip uninstall highflame highflame-sdk javelin_sdk -y # Build the package poetry build # Install the newly built package -pip install dist/javelin_sdk--py3-none-any.whl +pip install dist/highflame--py3-none-any.whl ``` -## [Universal Endpoints](https://docs.getjavelin.io/docs/javelin-core/integration#unified-endpoints) +### Development Notes + +For local development, change `version = "RELEASE_VERSION"` with any semantic version (e.g., `version = "2.0.1"`) in `pyproject.toml`. + +**⚠️ Important:** Make sure to revert `pyproject.toml` before committing to main. + +--- + +## Universal Endpoints Highflame provides universal endpoints that allow you to use a consistent interface across different LLM providers. Here are the main patterns: -#### Azure OpenAI +### Azure OpenAI + - [Basic Azure OpenAI integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/azure-openai/azure-universal.py) -- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/azure-openai/javelin_azureopenai_univ_endpoint.py) +- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/azure-openai/highflame_azureopenai_univ_endpoint.py) - [OpenAI-compatible interface](https://github.com/highflame-ai/highflame-python/blob/main/examples/azure-openai/openai_compatible_univ_azure.py) -#### Bedrock +### Bedrock + - [Basic Bedrock integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/bedrock/bedrock_client_universal.py) -- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/bedrock/javelin_bedrock_univ_endpoint.py) +- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/bedrock/highflame_bedrock_univ_endpoint.py) - [OpenAI-compatible interface](https://github.com/highflame-ai/highflame-python/blob/main/examples/bedrock/openai_compatible_univ_bedrock.py) -#### Gemini +### Gemini + - [Basic Gemini integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/gemini/gemini-universal.py) -- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/gemini/javelin_gemini_univ_endpoint.py) +- [Universal endpoint implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/gemini/highflame_gemini_univ_endpoint.py) - [OpenAI-compatible interface](https://github.com/highflame-ai/highflame-python/blob/main/examples/gemini/openai_compatible_univ_gemini.py) ### Agent Examples -- [CrewAI integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/agents/crewai_javelin.ipynb) -- [LangGraph integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/agents/langgraph_javelin.ipynb) + +- [CrewAI integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/agents/crewai_highflame.ipynb) +- [LangGraph integration](https://github.com/highflame-ai/highflame-python/blob/main/examples/agents/langgraph_highflame.ipynb) ### Basic Examples + - [Asynchronous example](https://github.com/highflame-ai/highflame-python/blob/main/examples/route_examples/aexample.py) - [Synchronous example](https://github.com/highflame-ai/highflame-python/blob/main/examples/route_examples/example.py) - [Drop-in replacement example](https://github.com/highflame-ai/highflame-python/blob/main/examples/route_examples/drop_in_replacement.py) ### Advanced Examples + - [Document processing](https://github.com/highflame-ai/highflame-python/blob/main/examples/gemini/document_processing.py) -- [RAG implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/rag/javelin_rag_embeddings_demo.ipynb) +- [RAG implementation](https://github.com/highflame-ai/highflame-python/blob/main/examples/rag/highflame_rag_embeddings_demo.ipynb) + +--- ## Additional Integration Patterns For more detailed examples and integration patterns, check out: -- [Azure OpenAI Integration](https://docs.getjavelin.io/docs/javelin-core/integration#2-azure-openai-api-endpoints) -- [AWS Bedrock Integration](https://docs.getjavelin.io/docs/javelin-core/integration#3-aws-bedrock-api-endpoints) -- [Supported Language Models](https://docs.getjavelin.io/docs/javelin-core/supported-llms) +- [Azure OpenAI Integration](https://docs.highflame.ai/documentation/getting-started/gateway-integration-examples#id-2-azure-openai-api-endpoints) +- [AWS Bedrock Integration](https://docs.highflame.ai/documentation/getting-started/gateway-integration-examples#id-3-aws-bedrock-api-endpoints) +- [CLI Reference](https://docs.highflame.ai/api-reference/cli) + +--- + +## Type Hints & py.typed Marker + +This package includes a `py.typed` marker file, which indicates to type checkers (like `mypy`, `pyright`, `pylance`) that the package supports type checking. This allows IDEs and static analysis tools to provide better autocomplete, type checking, and refactoring support. + +**Usage:** + +```python +# With py.typed, type checkers can validate this: +from highflame import Highflame, Config + +config: Config = Config(api_key="your-key") +client: Highflame = Highflame(config) +``` + +--- + +## Logging + +The SDK includes logging support for debugging and observability. Logging is configured at the module level using Python's standard `logging` module. + +### Basic Configuration + +```python +import logging + +# Enable debug logging for the SDK +logging.basicConfig(level=logging.DEBUG) + +# Or set logging for specific modules +logging.getLogger("highflame").setLevel(logging.DEBUG) +logging.getLogger("highflame.services").setLevel(logging.DEBUG) +``` + +### Logging Levels + +- **DEBUG** - Detailed information for diagnosing problems + - Client initialization + - Route queries + - Service operations + - Tracing configuration +- **INFO** - General informational messages +- **WARNING** - Warning messages for potentially problematic situations +- **ERROR** - Error messages for failures + +### Example: Full Debug Logging + +```python +import logging +from highflame import Highflame, Config + +# Configure detailed logging +logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) + +# Initialize client +config = Config(api_key="your-key") +client = Highflame(config) + +# Debug logs will show: +# - Client initialization with base URL +# - Route queries with route names +# - Tracing configuration (if enabled) +response = client.query_route( + route_name="my_route", + query_body={...} +) +``` + +### Production Configuration + +For production, use structured logging: + +```python +import logging +import json +from datetime import datetime + +# Use JSON logging for better observability +class JSONFormatter(logging.Formatter): + def format(self, record): + log_obj = { + "timestamp": datetime.utcnow().isoformat(), + "level": record.levelname, + "logger": record.name, + "message": record.getMessage(), + } + if record.exc_info: + log_obj["exception"] = self.formatException(record.exc_info) + return json.dumps(log_obj) + +# Configure handler +handler = logging.StreamHandler() +handler.setFormatter(JSONFormatter()) + +logger = logging.getLogger("highflame") +logger.addHandler(handler) +logger.setLevel(logging.INFO) +``` + +### Available Loggers + +| Logger | Purpose | +| ------------------------------------ | ----------------------------------- | +| `highflame.client` | Main Highflame client operations | +| `highflame.services.route_service` | Route querying and management | +| `highflame.services.gateway_service` | Gateway operations | +| `highflame.tracing_setup` | OpenTelemetry tracing configuration | + +--- + +## TODO + +### Code Quality Improvements + +- [ ] **Type Hints Coverage**: Add comprehensive type hints to all methods. Many internal methods currently return `Any` or lack return type annotations. Properties like `client`, `aclient`, `close()`, and helper methods need type hints. + +- [ ] **Error Handling**: Replace broad `except Exception` blocks (27+ locations) with specific exception types. This will improve debugging and error context. + +- [ ] **Backward Compatibility**: Phase out dual header support (`x-javelin-*` and `x-highflame-*`) after transition period. Create deprecation timeline and migration path. + +- [ ] **Request/Response Validation**: Add validation layer for requests and responses to catch errors early. + +- [ ] **HTTP Connection Pooling**: Add configuration options for HTTP connection pooling to improve performance. + +### CLI Improvements + +- [ ] **CLI Separation**: Separate CLI into its own `highflame-cli` package. Create separate repository, package, and PyPI distribution. + +- [ ] **CLI Error Messages**: Improve CLI error messages with troubleshooting hints and actionable guidance. + +- [ ] **CLI Testing**: Add comprehensive test suite for CLI commands and edge cases. + +- [ ] **CLI Documentation**: Update CLI documentation to reflect current bundled state vs. future separated state. + +### Reliability & Performance + +- [ ] **Automatic Retry Logic**: Implement retry logic with exponential backoff for transient failures. + +- [ ] **Rate Limit Detection**: Add automatic rate limit detection and backoff handling. + +- [ ] **Performance Metrics**: Add performance metrics tracking for requests, latency, and throughput. + +- [ ] **Circuit Breaker Pattern**: Implement circuit breaker pattern for resilience against failing services. + +- [ ] **Request Caching**: Add optional request caching layer for frequently accessed resources. + +### Developer Experience + +- [ ] **Deprecation Warnings**: Add deprecation warning module for v1 → v2 migration to help users transition. + +- [ ] **Structured Logging**: Enhance structured JSON logging implementation for production environments. + +- [ ] **Custom Middleware**: Add support for custom middleware to allow users to extend SDK functionality. + +- [ ] **Better Error Messages**: Implement error messages with troubleshooting steps and links to documentation. + +### Testing & Release + +- [ ] **Full Test Suite**: Run and expand comprehensive test suite covering all SDK functionality. + +- [ ] **Build & Distribution**: Test building distribution packages and verify installation process. + +- [ ] **Installation Testing**: Test `pip install highflame` and verify all imports work correctly. + +- [ ] **CLI Functionality Testing**: Test all CLI commands and verify they work as expected. + +- [ ] **Performance Testing**: Conduct performance testing and optimization. + +- [ ] **PyPI Publishing**: Publish `highflame` v2.0.0 to PyPI with proper release notes. + +- [ ] **Documentation Updates**: Update GitHub release notes and publish migration guide on docs site. + +### Architecture + +- [ ] **Client Class Refactoring**: Refactor large `Highflame` class (1645 lines) into smaller, focused classes for better maintainability. + +- [ ] **Constants Module**: Create centralized constants module for HTTP headers and configuration values. + +- [ ] **Service Layer Improvements**: Enhance service layer with better error handling and type safety. diff --git a/examples/agents/adk_gemini_agent_javelin/__init__.py b/examples/agents/adk_gemini_agent_highflame/__init__.py similarity index 100% rename from examples/agents/adk_gemini_agent_javelin/__init__.py rename to examples/agents/adk_gemini_agent_highflame/__init__.py diff --git a/examples/agents/adk_gemini_agent_javelin/agent.py b/examples/agents/adk_gemini_agent_highflame/agent.py similarity index 90% rename from examples/agents/adk_gemini_agent_javelin/agent.py rename to examples/agents/adk_gemini_agent_highflame/agent.py index 57aed1c..0eb3a2d 100644 --- a/examples/agents/adk_gemini_agent_javelin/agent.py +++ b/examples/agents/adk_gemini_agent_highflame/agent.py @@ -11,12 +11,12 @@ load_dotenv() GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") -JAVELIN_API_KEY = os.getenv("JAVELIN_API_KEY") +HIGHFLAME_API_KEY = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") if not GEMINI_API_KEY: raise ValueError("Missing GEMINI_API_KEY") -if not JAVELIN_API_KEY: - raise ValueError("Missing JAVELIN_API_KEY") +if not HIGHFLAME_API_KEY: + raise ValueError("Missing HIGHFLAME_API_KEY") # Agent 1: Researcher research_agent = LlmAgent( @@ -25,7 +25,7 @@ api_base="https://api-dev.javelin.live/v1/", extra_headers={ "x-javelin-route": "google_univ", - "x-api-key": JAVELIN_API_KEY, + "x-api-key": HIGHFLAME_API_KEY, "Authorization": f"Bearer {GEMINI_API_KEY}", }, ), @@ -41,7 +41,7 @@ api_base="https://api-dev.javelin.live/v1/", extra_headers={ "x-javelin-route": "google_univ", - "x-api-key": JAVELIN_API_KEY, + "x-api-key": HIGHFLAME_API_KEY, "Authorization": f"Bearer {GEMINI_API_KEY}", }, ), @@ -57,7 +57,7 @@ api_base="https://api-dev.javelin.live/v1/", extra_headers={ "x-javelin-route": "google_univ", - "x-api-key": JAVELIN_API_KEY, + "x-api-key": HIGHFLAME_API_KEY, "Authorization": f"Bearer {GEMINI_API_KEY}", }, ), diff --git a/examples/agents/adk_openai_agent_javelin/__init__.py b/examples/agents/adk_openai_agent_highflame/__init__.py similarity index 100% rename from examples/agents/adk_openai_agent_javelin/__init__.py rename to examples/agents/adk_openai_agent_highflame/__init__.py diff --git a/examples/agents/adk_openai_agent_javelin/agent.py b/examples/agents/adk_openai_agent_highflame/agent.py similarity index 97% rename from examples/agents/adk_openai_agent_javelin/agent.py rename to examples/agents/adk_openai_agent_highflame/agent.py index c1c98cb..babd14a 100644 --- a/examples/agents/adk_openai_agent_javelin/agent.py +++ b/examples/agents/adk_openai_agent_highflame/agent.py @@ -10,7 +10,7 @@ load_dotenv() -JAVELIN_API_KEY = os.getenv("JAVELIN_API_KEY") +JAVELIN_API_KEY = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") if not JAVELIN_API_KEY: diff --git a/examples/agents/crewai_javelin.ipynb b/examples/agents/crewai_highflame.ipynb similarity index 100% rename from examples/agents/crewai_javelin.ipynb rename to examples/agents/crewai_highflame.ipynb diff --git a/examples/agents/langgraph_javelin.ipynb b/examples/agents/langgraph_highflame.ipynb similarity index 100% rename from examples/agents/langgraph_javelin.ipynb rename to examples/agents/langgraph_highflame.ipynb diff --git a/examples/agents/openai_agents_javelin.py b/examples/agents/openai_agents_highflame.py similarity index 85% rename from examples/agents/openai_agents_javelin.py rename to examples/agents/openai_agents_highflame.py index a4668a6..1c23c30 100644 --- a/examples/agents/openai_agents_javelin.py +++ b/examples/agents/openai_agents_highflame.py @@ -11,7 +11,7 @@ ) from openai import AsyncOpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from dotenv import load_dotenv ############################################################################## @@ -23,20 +23,25 @@ set_default_openai_api("chat_completions") openai_api_key = os.getenv("OPENAI_API_KEY", "") -javelin_api_key = os.getenv("JAVELIN_API_KEY", "") -javelin_base_url = os.getenv("JAVELIN_BASE_URL", "") +highflame_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY", "") +) +highflame_base_url = ( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL", "") +) -if not (openai_api_key and javelin_api_key and javelin_base_url): +if not (openai_api_key and highflame_api_key and highflame_base_url): raise ValueError( - "Missing OPENAI_API_KEY, JAVELIN_API_KEY, or JAVELIN_BASE_URL in .env" + "Missing OPENAI_API_KEY, HIGHFLAME_API_KEY (or JAVELIN_API_KEY), " + "or HIGHFLAME_BASE_URL (or JAVELIN_BASE_URL) in .env" ) # Create async OpenAI client async_openai_client = AsyncOpenAI(api_key=openai_api_key) -# Register with Javelin +# Register with Highflame javelin_client = JavelinClient( - JavelinConfig(javelin_api_key=javelin_api_key, base_url=javelin_base_url) + JavelinConfig(javelin_api_key=highflame_api_key, base_url=highflame_base_url) ) # Adjust route name if needed javelin_client.register_openai(async_openai_client, route_name="openai_univ") diff --git a/examples/anthropic/anthropic_api_function_calling.py b/examples/anthropic/anthropic_api_function_calling.py index 4721bd6..72f7132 100644 --- a/examples/anthropic/anthropic_api_function_calling.py +++ b/examples/anthropic/anthropic_api_function_calling.py @@ -1,13 +1,13 @@ import os from dotenv import load_dotenv -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() # Config setup config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("ANTHROPIC_API_KEY"), timeout=120, ) diff --git a/examples/anthropic/anthropic_function_call.py b/examples/anthropic/anthropic_function_call.py index cff52e9..4751a10 100644 --- a/examples/anthropic/anthropic_function_call.py +++ b/examples/anthropic/anthropic_function_call.py @@ -2,7 +2,7 @@ import os import json import asyncio -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Load environment variables from dotenv import load_dotenv @@ -11,8 +11,8 @@ # Javelin Setup config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), ) client = JavelinClient(config) diff --git a/examples/anthropic/javelin_anthropic_api_call.py b/examples/anthropic/highflame_anthropic_api_call.py similarity index 87% rename from examples/anthropic/javelin_anthropic_api_call.py rename to examples/anthropic/highflame_anthropic_api_call.py index 7ca4dd1..bb1af4d 100644 --- a/examples/anthropic/javelin_anthropic_api_call.py +++ b/examples/anthropic/highflame_anthropic_api_call.py @@ -1,7 +1,7 @@ import os import json from typing import Dict, Any -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from dotenv import load_dotenv load_dotenv() @@ -16,8 +16,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Javelin client config config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("ANTHROPIC_API_KEY"), timeout=120, ) diff --git a/examples/anthropic/javelin_anthropic_univ_endpoint.py b/examples/anthropic/highflame_anthropic_univ_endpoint.py similarity index 85% rename from examples/anthropic/javelin_anthropic_univ_endpoint.py rename to examples/anthropic/highflame_anthropic_univ_endpoint.py index a08be62..2359e5c 100644 --- a/examples/anthropic/javelin_anthropic_univ_endpoint.py +++ b/examples/anthropic/highflame_anthropic_univ_endpoint.py @@ -3,7 +3,7 @@ import os from typing import Any, Dict -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import dotenv @@ -18,8 +18,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration for Bedrock config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), ) client = JavelinClient(config) headers = { diff --git a/examples/anthropic/openai_compatible_univ_anthropic.py b/examples/anthropic/openai_compatible_univ_anthropic.py index e5486af..2a8a135 100644 --- a/examples/anthropic/openai_compatible_univ_anthropic.py +++ b/examples/anthropic/openai_compatible_univ_anthropic.py @@ -1,4 +1,4 @@ -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os from typing import Dict, Any import json @@ -15,8 +15,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), timeout=120, ) diff --git a/examples/azure-openai/azure-universal.py b/examples/azure-openai/azure-universal.py index dc8297f..c46678a 100644 --- a/examples/azure-openai/azure-universal.py +++ b/examples/azure-openai/azure-universal.py @@ -3,7 +3,7 @@ from dotenv import load_dotenv from openai import AzureOpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() @@ -13,7 +13,10 @@ def initialize_client(): Creates the AzureOpenAI client and registers it with Javelin. Returns the AzureOpenAI client object if successful, else None. """ - javelin_api_key = os.getenv("JAVELIN_API_KEY") # add your javelin api key here + # add your API key here + javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ) azure_openai_api_key = os.getenv( "AZURE_OPENAI_API_KEY" ) # Add your Azure OpenAI key diff --git a/examples/azure-openai/azure_function_call.py b/examples/azure-openai/azure_function_call.py index 1925ee0..f79e53b 100644 --- a/examples/azure-openai/azure_function_call.py +++ b/examples/azure-openai/azure_function_call.py @@ -2,17 +2,17 @@ import os from dotenv import load_dotenv from openai import AzureOpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() def init_azure_client_with_javelin(): azure_api_key = os.getenv("AZURE_OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + highflame_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") - if not azure_api_key or not javelin_api_key: - raise ValueError("Missing AZURE_OPENAI_API_KEY or JAVELIN_API_KEY") + if not azure_api_key or not highflame_api_key: + raise ValueError("Missing AZURE_OPENAI_API_KEY or HIGHFLAME_API_KEY") # Azure OpenAI setup azure_client = AzureOpenAI( @@ -21,8 +21,8 @@ def init_azure_client_with_javelin(): api_key=azure_api_key, ) - # Register with Javelin - config = JavelinConfig(javelin_api_key=javelin_api_key) + # Register with Highflame + config = JavelinConfig(javelin_api_key=highflame_api_key) client = JavelinClient(config) client.register_azureopenai(azure_client, route_name="azureopenai_univ") diff --git a/examples/azure-openai/azure_general_route.py b/examples/azure-openai/azure_general_route.py index 59aec58..a738fab 100644 --- a/examples/azure-openai/azure_general_route.py +++ b/examples/azure-openai/azure_general_route.py @@ -16,7 +16,7 @@ def init_azure_client_sync(): """ try: llm_api_key = os.getenv("AZURE_OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") if not llm_api_key or not javelin_api_key: raise Exception( "AZURE_OPENAI_API_KEY and JAVELIN_API_KEY must be set in " @@ -25,7 +25,10 @@ def init_azure_client_sync(): javelin_headers = {"x-javelin-apikey": javelin_api_key} client = AzureOpenAI( api_key=llm_api_key, - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1/query/azure-openai", + base_url=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1/query/azure-openai" + ), default_headers=javelin_headers, api_version="2024-02-15-preview", ) @@ -39,7 +42,7 @@ def init_azure_embeddings_client_sync(): """Initialize a synchronous AzureOpenAI client for embeddings.""" try: llm_api_key = os.getenv("AZURE_OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") if not llm_api_key or not javelin_api_key: raise Exception( "AZURE_OPENAI_API_KEY and JAVELIN_API_KEY must be set in " @@ -134,7 +137,7 @@ async def init_async_azure_client(): """Initialize an asynchronous AzureOpenAI client for chat completions.""" try: llm_api_key = os.getenv("AZURE_OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") if not llm_api_key or not javelin_api_key: raise Exception( "AZURE_OPENAI_API_KEY and JAVELIN_API_KEY must be set in " @@ -144,7 +147,10 @@ async def init_async_azure_client(): # Include the API version in the base URL for the async client. client = AsyncOpenAI( api_key=llm_api_key, - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1/query/azure-openai", + base_url=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1/query/azure-openai" + ), default_headers=javelin_headers, ) return client diff --git a/examples/azure-openai/azure_openai_javelin_stream_&_non-stream.js b/examples/azure-openai/azure_openai_highflame_stream_&_non-stream.js similarity index 100% rename from examples/azure-openai/azure_openai_javelin_stream_&_non-stream.js rename to examples/azure-openai/azure_openai_highflame_stream_&_non-stream.js diff --git a/examples/azure-openai/javelin_azureopenai_univ_endpoint.py b/examples/azure-openai/highflame_azureopenai_univ_endpoint.py similarity index 79% rename from examples/azure-openai/javelin_azureopenai_univ_endpoint.py rename to examples/azure-openai/highflame_azureopenai_univ_endpoint.py index 170579f..0fd34e5 100644 --- a/examples/azure-openai/javelin_azureopenai_univ_endpoint.py +++ b/examples/azure-openai/highflame_azureopenai_univ_endpoint.py @@ -3,7 +3,7 @@ import os from typing import Any, Dict -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from dotenv import load_dotenv load_dotenv() @@ -18,12 +18,12 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), default_headers={ "Content-Type": "application/json", "x-javelin-provider": "https://javelinpreview.openai.azure.com/openai", - "x-api-key": os.getenv("JAVELIN_API_KEY"), + "x-api-key": os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), "api-key": os.getenv("AZURE_OPENAI_API_KEY"), }, ) @@ -40,7 +40,10 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "Content-Type": "application/json", "x-javelin-route": "azureopenai_univ", "x-javelin-provider": "https://javelinpreview.openai.azure.com/openai", - "x-api-key": os.getenv("JAVELIN_API_KEY"), # Use environment variable for security + # Use environment variable for security + "x-api-key": ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ), "api-key": os.getenv( "AZURE_OPENAI_API_KEY" ), # Use environment variable for security diff --git a/examples/azure-openai/langchain_azure_universal.py b/examples/azure-openai/langchain_azure_universal.py index 3c84f71..ce5d929 100644 --- a/examples/azure-openai/langchain_azure_universal.py +++ b/examples/azure-openai/langchain_azure_universal.py @@ -12,8 +12,8 @@ print("Initializing environment variables...") load_dotenv() azure_openai_api_key = os.getenv("AZURE_OPENAI_API_KEY") -javelin_api_key = os.getenv("JAVELIN_API_KEY") -base_url = os.getenv("JAVELIN_BASE_URL") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +base_url = os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") # The name of your Azure deployment (e.g., "gpt35") # or whatever you’ve set in Azure. Must also match x-javelin-model if diff --git a/examples/azure-openai/langchain_chatmodel_example.py b/examples/azure-openai/langchain_chatmodel_example.py index 53a4934..859caef 100644 --- a/examples/azure-openai/langchain_chatmodel_example.py +++ b/examples/azure-openai/langchain_chatmodel_example.py @@ -4,7 +4,10 @@ dotenv.load_dotenv() -url = os.path.join(os.getenv("JAVELIN_BASE_URL"), "v1") +base_url = ( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") +) +url = os.path.join(base_url, "v1") print(url) model = AzureChatOpenAI( azure_endpoint=url, @@ -12,7 +15,10 @@ openai_api_version="2023-03-15-preview", extra_headers={ "x-javelin-route": "azureopenai_univ", - "x-api-key": os.environ.get("JAVELIN_API_KEY"), + "x-api-key": ( + os.environ.get("HIGHFLAME_API_KEY") + or os.environ.get("JAVELIN_API_KEY") + ), }, ) diff --git a/examples/azure-openai/openai_compatible_univ_azure.py b/examples/azure-openai/openai_compatible_univ_azure.py index d3264ab..393f9bd 100644 --- a/examples/azure-openai/openai_compatible_univ_azure.py +++ b/examples/azure-openai/openai_compatible_univ_azure.py @@ -6,7 +6,7 @@ # regardless of the underlying model provider, with Javelin handling the # necessary translations and adaptations behind the scenes. -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os from typing import Dict, Any import json @@ -20,8 +20,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), timeout=120, ) diff --git a/examples/bedrock/bedrock_client.py b/examples/bedrock/bedrock_client.py index 1e0a4f3..ee27a11 100644 --- a/examples/bedrock/bedrock_client.py +++ b/examples/bedrock/bedrock_client.py @@ -2,13 +2,13 @@ import base64 import requests from openai import OpenAI, AsyncOpenAI, AzureOpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from pydantic import BaseModel # Environment Variables -javelin_base_url = os.getenv("JAVELIN_BASE_URL") +javelin_base_url = os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") openai_api_key = os.getenv("OPENAI_API_KEY") -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") gemini_api_key = os.getenv("GEMINI_API_KEY") # Global JavelinClient, used for everything diff --git a/examples/bedrock/bedrock_client_universal.py b/examples/bedrock/bedrock_client_universal.py index 204bd8e..775ffda 100644 --- a/examples/bedrock/bedrock_client_universal.py +++ b/examples/bedrock/bedrock_client_universal.py @@ -4,7 +4,7 @@ import boto3 from dotenv import load_dotenv -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() @@ -22,7 +22,7 @@ def init_bedrock(): config = JavelinConfig( # Replace with your Javelin API key - javelin_api_key=os.getenv("JAVELIN_API_KEY") + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") ) javelin_client = JavelinClient(config) javelin_client.register_bedrock( diff --git a/examples/bedrock/bedrock_function_tool_call.py b/examples/bedrock/bedrock_function_tool_call.py index c2bf474..cdd64e5 100644 --- a/examples/bedrock/bedrock_function_tool_call.py +++ b/examples/bedrock/bedrock_function_tool_call.py @@ -4,7 +4,7 @@ import os from typing import Dict, Any -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Load ENV from dotenv import load_dotenv @@ -21,8 +21,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup Bedrock Javelin client config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), ) client = JavelinClient(config) @@ -30,7 +30,7 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "Content-Type": "application/json", "x-javelin-route": "amazon_univ", "x-javelin-model": "amazon.titan-text-express-v1", # replace if needed - "x-api-key": os.getenv("JAVELIN_API_KEY"), + "x-api-key": os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), } diff --git a/examples/bedrock/bedrock_general_route.py b/examples/bedrock/bedrock_general_route.py index cc53ee5..3c58b66 100644 --- a/examples/bedrock/bedrock_general_route.py +++ b/examples/bedrock/bedrock_general_route.py @@ -56,7 +56,10 @@ def get_bedrock_client(): aws_access_key_id = os.getenv("AWS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY") aws_secret_access_key = os.getenv("AWS_SECRET_ACCESS_KEY", "YOUR_SECRET_KEY") - bedrock_api_key = os.getenv("JAVELIN_API_KEY", "YOUR_BEDROCK_API_KEY") + bedrock_api_key = ( + os.getenv("HIGHFLAME_API_KEY") + or os.getenv("JAVELIN_API_KEY", "YOUR_BEDROCK_API_KEY") + ) custom_headers = { "x-javelin-apikey": bedrock_api_key, @@ -66,7 +69,10 @@ def get_bedrock_client(): client = boto3.client( service_name="bedrock-runtime", region_name="us-east-1", - endpoint_url=os.path.join(os.getenv("JAVELIN_BASE_URL"), "v1"), + endpoint_url=os.path.join( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + "v1", + ), aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, ) diff --git a/examples/bedrock/javelin_bedrock_univ_endpoint.py b/examples/bedrock/highflame_bedrock_univ_endpoint.py similarity index 81% rename from examples/bedrock/javelin_bedrock_univ_endpoint.py rename to examples/bedrock/highflame_bedrock_univ_endpoint.py index 76c2be2..54ad350 100644 --- a/examples/bedrock/javelin_bedrock_univ_endpoint.py +++ b/examples/bedrock/highflame_bedrock_univ_endpoint.py @@ -3,7 +3,7 @@ import os from typing import Any, Dict -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Helper function to pretty print responses @@ -14,15 +14,15 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration for Bedrock config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), ) client = JavelinClient(config) headers = { "Content-Type": "application/json", "x-javelin-route": "univ_bedrock", "x-javelin-model": "amazon.titan-text-express-v1", - "x-api-key": os.getenv("JAVELIN_API_KEY"), + "x-api-key": os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), } # Example messages in OpenAI format diff --git a/examples/bedrock/langchain-bedrock-universal.py b/examples/bedrock/langchain-bedrock-universal.py index 4844727..61e740a 100644 --- a/examples/bedrock/langchain-bedrock-universal.py +++ b/examples/bedrock/langchain-bedrock-universal.py @@ -4,7 +4,7 @@ import boto3 from dotenv import load_dotenv -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() @@ -28,7 +28,10 @@ def init_bedrock(): # Initialize Javelin client config = JavelinConfig( - javelin_api_key=os.getenv("JAVELIN_API_KEY") # add your Javelin API key here + # add your API key here + javelin_api_key=( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ) ) javelin_client = JavelinClient(config) diff --git a/examples/bedrock/openai_compatible_univ_bedrock.py b/examples/bedrock/openai_compatible_univ_bedrock.py index a089e6f..3f9c267 100644 --- a/examples/bedrock/openai_compatible_univ_bedrock.py +++ b/examples/bedrock/openai_compatible_univ_bedrock.py @@ -1,4 +1,4 @@ -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os from typing import Dict, Any import json @@ -12,8 +12,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), timeout=120, ) diff --git a/examples/gemini/document_processing.py b/examples/gemini/document_processing.py index b2203e2..f2649cc 100644 --- a/examples/gemini/document_processing.py +++ b/examples/gemini/document_processing.py @@ -3,11 +3,11 @@ from openai import OpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Environment Variables openai_api_key = os.getenv("OPENAI_API_KEY") -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") gemini_api_key = os.getenv("GEMINI_API_KEY") # Initialize Javelin Client @@ -19,9 +19,14 @@ # Initialize Javelin Client def initialize_javelin_client(): - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ) + base_url = ( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") + ) config = JavelinConfig( - javelin_api_key=javelin_api_key, base_url=os.getenv("JAVELIN_BASE_URL") + javelin_api_key=javelin_api_key, base_url=base_url ) return JavelinClient(config) diff --git a/examples/gemini/gemini-universal.py b/examples/gemini/gemini-universal.py index 5427b38..9f95745 100644 --- a/examples/gemini/gemini-universal.py +++ b/examples/gemini/gemini-universal.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv from openai import OpenAI from pydantic import BaseModel -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() @@ -17,7 +17,7 @@ def init_gemini_client(): base_url="https://generativelanguage.googleapis.com/v1beta/openai/", ) - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig(javelin_api_key=javelin_api_key) client = JavelinClient(config) client.register_gemini(openai_client, route_name="google_univ") diff --git a/examples/gemini/gemini_function_tool_call.py b/examples/gemini/gemini_function_tool_call.py index a894bd5..d73d926 100644 --- a/examples/gemini/gemini_function_tool_call.py +++ b/examples/gemini/gemini_function_tool_call.py @@ -2,14 +2,14 @@ import os from dotenv import load_dotenv from openai import OpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig load_dotenv() def init_gemini_client(): gemini_api_key = os.getenv("GEMINI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") if not gemini_api_key or not javelin_api_key: raise ValueError("Missing GEMINI_API_KEY or JAVELIN_API_KEY") diff --git a/examples/gemini/javelin_gemini_univ_endpoint.py b/examples/gemini/highflame_gemini_univ_endpoint.py similarity index 81% rename from examples/gemini/javelin_gemini_univ_endpoint.py rename to examples/gemini/highflame_gemini_univ_endpoint.py index d9e09bd..6bb1d38 100644 --- a/examples/gemini/javelin_gemini_univ_endpoint.py +++ b/examples/gemini/highflame_gemini_univ_endpoint.py @@ -3,7 +3,7 @@ import os from typing import Any, Dict -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Helper function to pretty print responses @@ -14,8 +14,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("OPENAI_API_KEY"), ) client = JavelinClient(config) @@ -32,7 +32,10 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "x-javelin-route": "google_univ", "x-javelin-model": "gemini-1.5-flash", "x-javelin-provider": "https://generativelanguage.googleapis.com/v1beta/openai", - "x-api-key": os.getenv("JAVELIN_API_KEY"), # Use environment variable for security + # Use environment variable for security + "x-api-key": ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ), # Use environment variable for security "Authorization": f"Bearer {os.getenv('GEMINI_API_KEY')}", } diff --git a/examples/gemini/langchain_chatmodel_example.py b/examples/gemini/langchain_chatmodel_example.py index 3eedbb9..6290caa 100644 --- a/examples/gemini/langchain_chatmodel_example.py +++ b/examples/gemini/langchain_chatmodel_example.py @@ -8,10 +8,13 @@ model = init_chat_model( "gemini-1.5-flash", model_provider="openai", - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1", + base_url=f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}/v1", extra_headers={ "x-javelin-route": "google_univ", - "x-api-key": os.environ.get("JAVELIN_API_KEY"), + "x-api-key": ( + os.environ.get("HIGHFLAME_API_KEY") + or os.environ.get("JAVELIN_API_KEY") + ), "Authorization": f"Bearer {os.environ.get('GEMINI_API_KEY')}", }, ) diff --git a/examples/gemini/openai_compatible_univ_gemini.py b/examples/gemini/openai_compatible_univ_gemini.py index 0dae7ae..349b948 100644 --- a/examples/gemini/openai_compatible_univ_gemini.py +++ b/examples/gemini/openai_compatible_univ_gemini.py @@ -6,7 +6,7 @@ # regardless of the underlying model provider, with Javelin handling the # necessary translations and adaptations behind the scenes. -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os from typing import Dict, Any import json @@ -20,8 +20,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("OPENAI_API_KEY"), timeout=120, ) @@ -31,7 +31,10 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "Content-Type": "application/json", "x-javelin-route": "google_univ", "x-javelin-provider": "https://generativelanguage.googleapis.com/v1beta/openai", - "x-api-key": os.getenv("JAVELIN_API_KEY"), # Use environment variable for security + # Use environment variable for security + "x-api-key": ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ), # Use environment variable for security "Authorization": f"Bearer {os.getenv('GEMINI_API_KEY')}", } diff --git a/examples/gemini/strawberry.py b/examples/gemini/strawberry.py index a4748b6..3d75fa1 100644 --- a/examples/gemini/strawberry.py +++ b/examples/gemini/strawberry.py @@ -2,11 +2,11 @@ from openai import OpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Environment Variables openai_api_key = os.getenv("OPENAI_API_KEY") -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") gemini_api_key = os.getenv("GEMINI_API_KEY") # Initialize Javelin Client @@ -43,9 +43,9 @@ def openai_chat_completions(): # Initialize Javelin Client def initialize_javelin_client(): - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), javelin_api_key=javelin_api_key, ) return JavelinClient(config) diff --git a/examples/guardrails/langgraph_guardrails_mcp_example.py b/examples/guardrails/langgraph_guardrails_mcp_example.py index ee78300..d4cbdf9 100644 --- a/examples/guardrails/langgraph_guardrails_mcp_example.py +++ b/examples/guardrails/langgraph_guardrails_mcp_example.py @@ -25,8 +25,8 @@ # Configuration from environment variables OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") -JAVELIN_API_KEY = os.getenv("JAVELIN_API_KEY") -BASE_URL = os.getenv("JAVELIN_BASE_URL") +JAVELIN_API_KEY = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +BASE_URL = os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") MODEL_NAME_CHAT = os.getenv("MODEL_NAME_CHAT", "openai/gpt-4o-mini") JAVELIN_GUARDRAILS_URL = os.getenv( "JAVELIN_GUARDRAILS_URL", "https://javelin-guardrails.fastmcp.app/mcp" @@ -133,7 +133,7 @@ async def main(): Main function demonstrating the Guardrails MCP Agent. """ # Validate required environment variables - required_vars = ["OPENAI_API_KEY", "JAVELIN_API_KEY", "JAVELIN_BASE_URL"] + required_vars = ["OPENAI_API_KEY"] # JAVELIN_* vars now have HIGHFLAME_* fallback missing_vars = [var for var in required_vars if not os.getenv(var)] if missing_vars: diff --git a/examples/guardrails/test_guardrails.py b/examples/guardrails/test_guardrails.py index c037740..50c02e4 100644 --- a/examples/guardrails/test_guardrails.py +++ b/examples/guardrails/test_guardrails.py @@ -1,8 +1,8 @@ import os -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Use your actual API key here -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig( base_url="https://api-dev.javelin.live", javelin_api_key=javelin_api_key diff --git a/examples/mistral/mistral_function_tool_call.py b/examples/mistral/mistral_function_tool_call.py index f7e74d9..19b3cc5 100644 --- a/examples/mistral/mistral_function_tool_call.py +++ b/examples/mistral/mistral_function_tool_call.py @@ -10,7 +10,10 @@ def init_mistral_model(): return init_chat_model( model_name="mistral-large-latest", model_provider="openai", - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1", + base_url=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1" + ), extra_headers={ "x-javelin-route": "mistral_univ", "x-api-key": os.environ.get("OPENAI_API_KEY"), diff --git a/examples/openai/javelin_openai_univ_endpoint.py b/examples/openai/highflame_openai_univ_endpoint.py similarity index 79% rename from examples/openai/javelin_openai_univ_endpoint.py rename to examples/openai/highflame_openai_univ_endpoint.py index 68455ab..10b3d9c 100644 --- a/examples/openai/javelin_openai_univ_endpoint.py +++ b/examples/openai/highflame_openai_univ_endpoint.py @@ -3,7 +3,7 @@ import os from typing import Any, Dict -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig # Helper function to pretty print responses @@ -14,8 +14,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("OPENAI_API_KEY"), ) client = JavelinClient(config) @@ -32,7 +32,10 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "x-javelin-route": "openai_univ", "x-javelin-model": "gpt-4", "x-javelin-provider": "https://api.openai.com/v1", - "x-api-key": os.getenv("JAVELIN_API_KEY"), # Use environment variable for security + # Use environment variable for security + "x-api-key": ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ), # Use environment variable for security "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", } diff --git a/examples/openai/img_generations_example.py b/examples/openai/img_generations_example.py index c1c12d2..c5a698d 100644 --- a/examples/openai/img_generations_example.py +++ b/examples/openai/img_generations_example.py @@ -1,13 +1,13 @@ import base64 from openai import OpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os import dotenv dotenv.load_dotenv() # Load API keys from environment variables -JAVELIN_API_KEY = os.getenv("JAVELIN_API_KEY") +JAVELIN_API_KEY = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") LLM_API_KEY = os.getenv("LLM_API_KEY") BASE_URL = os.getenv("BASE_URL") diff --git a/examples/openai/langchain-openai-universal.py b/examples/openai/langchain-openai-universal.py index 52ad932..9bded68 100644 --- a/examples/openai/langchain-openai-universal.py +++ b/examples/openai/langchain-openai-universal.py @@ -16,11 +16,17 @@ # 1) Configuration # ----------------------------------------------------------------------------- OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") # add your openai api key here -JAVELIN_API_KEY = os.environ.get("JAVELIN_API_KEY") # add your javelin api key here +# add your javelin api key here +JAVELIN_API_KEY = ( + os.environ.get("HIGHFLAME_API_KEY") or os.environ.get("JAVELIN_API_KEY") +) MODEL_NAME_CHAT = "gpt-3.5-turbo" # For chat MODEL_NAME_EMBED = "text-embedding-ada-002" ROUTE_NAME = "openai_univ" -BASE_URL = os.getenv("JAVELIN_BASE_URL") # Default base URL +# Default base URL +BASE_URL = ( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") +) def init_chat_llm_non_streaming(): diff --git a/examples/openai/langchain_callback_example.py b/examples/openai/langchain_callback_example.py index 2c874e8..8ac48c5 100644 --- a/examples/openai/langchain_callback_example.py +++ b/examples/openai/langchain_callback_example.py @@ -13,7 +13,10 @@ class HeaderCallbackHandler(BaseCallbackHandler): """Custom callback handler that modifies the headers on chat model start.""" def __init__(self): - self.api_key = os.environ.get("JAVELIN_API_KEY") + self.api_key = ( + os.environ.get("HIGHFLAME_API_KEY") + or os.environ.get("JAVELIN_API_KEY") + ) def on_chain_start( self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any @@ -57,7 +60,10 @@ def on_chat_model_start( base_url="http://127.0.0.1:8000/v1", extra_headers={ "x-javelin-route": "openai_univ", - "x-api-key": os.environ.get("JAVELIN_API_KEY"), + "x-api-key": ( + os.environ.get("HIGHFLAME_API_KEY") + or os.environ.get("JAVELIN_API_KEY") + ), }, callbacks=[callback_handler], # Add our custom callback handler ) diff --git a/examples/openai/langchain_chatmodel_example.py b/examples/openai/langchain_chatmodel_example.py index 802481b..dc75613 100644 --- a/examples/openai/langchain_chatmodel_example.py +++ b/examples/openai/langchain_chatmodel_example.py @@ -8,10 +8,13 @@ model = init_chat_model( "gpt-4o-mini", model_provider="openai", - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1", + base_url=f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}/v1", extra_headers={ "x-javelin-route": "openai_univ", - "x-api-key": os.environ.get("JAVELIN_API_KEY"), + "x-api-key": ( + os.environ.get("HIGHFLAME_API_KEY") + or os.environ.get("JAVELIN_API_KEY") + ), }, ) diff --git a/examples/openai/o1-03_function-calling.py b/examples/openai/o1-03_function-calling.py index 998019e..79c6f70 100644 --- a/examples/openai/o1-03_function-calling.py +++ b/examples/openai/o1-03_function-calling.py @@ -5,7 +5,7 @@ import argparse from dotenv import load_dotenv from openai import OpenAI, AzureOpenAI -from javelin_sdk import JavelinClient, JavelinConfig, RouteNotFoundError +from highflame_sdk import JavelinClient, JavelinConfig, RouteNotFoundError # Load environment variables once at the start load_dotenv() @@ -21,7 +21,7 @@ def init_openai_client(): def init_javelin_client(openai_client, route_name="openai_univ"): - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig(javelin_api_key=javelin_api_key) client = JavelinClient(config) client.register_openai(openai_client, route_name=route_name) @@ -159,7 +159,7 @@ def init_azure_client(): def init_javelin_client_azure(azure_client, route_name="azureopenai_univ"): - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig(javelin_api_key=javelin_api_key) client = JavelinClient(config) client.register_azureopenai(azure_client, route_name=route_name) @@ -297,7 +297,7 @@ def openai_regular_non_stream(): "\n==== Running OpenAI Regular Route Non-Streaming Function " "Calling Example ====" ) - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") llm_api_key = os.getenv("OPENAI_API_KEY") if not javelin_api_key or not llm_api_key: raise ValueError("Both JAVELIN_API_KEY and OPENAI_API_KEY must be set.") @@ -341,7 +341,7 @@ def openai_regular_stream(): print( "\n==== Running OpenAI Regular Route Streaming Function " "Calling Example ====" ) - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") llm_api_key = os.getenv("OPENAI_API_KEY") if not javelin_api_key or not llm_api_key: raise ValueError("Both JAVELIN_API_KEY and OPENAI_API_KEY must be set.") diff --git a/examples/openai/openai-universal.py b/examples/openai/openai-universal.py index 4942b72..d7536da 100644 --- a/examples/openai/openai-universal.py +++ b/examples/openai/openai-universal.py @@ -1,4 +1,4 @@ -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from openai import AsyncOpenAI, OpenAI import asyncio import os @@ -31,7 +31,7 @@ def init_javelin_client_sync(openai_client): """Initialize JavelinClient for synchronous usage and register the OpenAI route.""" try: # Set (and print) the Javelin key - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") config = JavelinConfig( javelin_api_key=javelin_api_key, ) @@ -111,9 +111,15 @@ def init_async_openai_client(): def init_javelin_client_async(openai_async_client): """Initialize JavelinClient for async usage and register the OpenAI route.""" try: - javelin_api_key = os.getenv("JAVELIN_API_KEY") # add your javelin api key here + # add your javelin api key here + javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ) + base_url = ( + os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") + ) config = JavelinConfig( - javelin_api_key=javelin_api_key, base_url=os.getenv("JAVELIN_BASE_URL") + javelin_api_key=javelin_api_key, base_url=base_url ) client = JavelinClient(config) client.register_openai(openai_async_client, route_name="openai_univ") diff --git a/examples/openai/openai_client.py b/examples/openai/openai_client.py index 1e0a4f3..ee27a11 100644 --- a/examples/openai/openai_client.py +++ b/examples/openai/openai_client.py @@ -2,13 +2,13 @@ import base64 import requests from openai import OpenAI, AsyncOpenAI, AzureOpenAI -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig from pydantic import BaseModel # Environment Variables -javelin_base_url = os.getenv("JAVELIN_BASE_URL") +javelin_base_url = os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL") openai_api_key = os.getenv("OPENAI_API_KEY") -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") gemini_api_key = os.getenv("GEMINI_API_KEY") # Global JavelinClient, used for everything diff --git a/examples/openai/openai_compatible_univ.py b/examples/openai/openai_compatible_univ.py index ae682db..1d39257 100644 --- a/examples/openai/openai_compatible_univ.py +++ b/examples/openai/openai_compatible_univ.py @@ -6,7 +6,7 @@ # pattern regardless of the underlying model provider, with Javelin handling # the necessary translations and adaptations behind the scenes. -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig import os from typing import Dict, Any import json @@ -20,8 +20,8 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: # Setup client configuration config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), - javelin_api_key=os.getenv("JAVELIN_API_KEY"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), + javelin_api_key=os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY"), llm_api_key=os.getenv("OPENAI_API_KEY"), timeout=120, ) @@ -31,7 +31,10 @@ def print_response(provider: str, response: Dict[str, Any]) -> None: "Content-Type": "application/json", "x-javelin-route": "openai_univ", "x-javelin-provider": "https://api.openai.com/v1", - "x-api-key": os.getenv("JAVELIN_API_KEY"), # Use environment variable for security + # Use environment variable for security + "x-api-key": ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ), # Use environment variable for security "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", } diff --git a/examples/openai/openai_embedding_example.py b/examples/openai/openai_embedding_example.py index 238c5b6..7daaa4a 100644 --- a/examples/openai/openai_embedding_example.py +++ b/examples/openai/openai_embedding_example.py @@ -7,7 +7,7 @@ dotenv.load_dotenv() -javelin_api_key = os.getenv("JAVELIN_API_KEY") +javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") llm_api_key = os.getenv("OPENAI_API_KEY") embeddings = OpenAIEmbeddings(openai_api_key=llm_api_key) @@ -37,7 +37,10 @@ javelin_headers = {"x-api-key": javelin_api_key, "x-javelin-route": "myusers"} llm = ChatOpenAI( - openai_api_base=f"{os.getenv('JAVELIN_BASE_URL')}/v1/query", + openai_api_base=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1/query" + ), openai_api_key=llm_api_key, model_kwargs={"extra_headers": javelin_headers}, ) diff --git a/examples/openai/openai_general_route.py b/examples/openai/openai_general_route.py index 1ed1052..8860f01 100644 --- a/examples/openai/openai_general_route.py +++ b/examples/openai/openai_general_route.py @@ -15,13 +15,16 @@ def init_sync_openai_client(): """Initialize and return a synchronous OpenAI client with Javelin headers.""" try: openai_api_key = os.getenv("OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") javelin_headers = {"x-javelin-apikey": javelin_api_key} print(f"[DEBUG] Synchronous OpenAI client key: {openai_api_key}") # This client is configured for chat completions. return OpenAI( api_key=openai_api_key, - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1", + base_url=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1" + ), default_headers=javelin_headers, ) except Exception as e: @@ -32,11 +35,16 @@ def init_async_openai_client(): """Initialize and return an asynchronous OpenAI client with Javelin headers.""" try: openai_api_key = os.getenv("OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") + ) javelin_headers = {"x-javelin-apikey": javelin_api_key} return AsyncOpenAI( api_key=openai_api_key, - base_url=f"{os.getenv('JAVELIN_BASE_URL')}/v1", + base_url=( + f"{os.getenv('HIGHFLAME_BASE_URL') or os.getenv('JAVELIN_BASE_URL')}" + "/v1" + ), default_headers=javelin_headers, ) except Exception as e: @@ -96,7 +104,7 @@ def sync_openai_embeddings(_): """ try: openai_api_key = os.getenv("OPENAI_API_KEY") - javelin_api_key = os.getenv("JAVELIN_API_KEY") + javelin_api_key = os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") javelin_headers = {"x-javelin-apikey": javelin_api_key} # Create a new client instance for embeddings. embeddings_client = OpenAI( diff --git a/examples/openai/openai_javelin_stream&non-stream.js b/examples/openai/openai_highflame_stream&non-stream.js similarity index 100% rename from examples/openai/openai_javelin_stream&non-stream.js rename to examples/openai/openai_highflame_stream&non-stream.js diff --git a/examples/rag/javelin_rag_embeddings_demo.ipynb b/examples/rag/highflame_rag_embeddings_demo.ipynb similarity index 100% rename from examples/rag/javelin_rag_embeddings_demo.ipynb rename to examples/rag/highflame_rag_embeddings_demo.ipynb diff --git a/examples/rag/rag_implemetation_javelin.ipynb b/examples/rag/rag_implemetation_highflame.ipynb similarity index 100% rename from examples/rag/rag_implemetation_javelin.ipynb rename to examples/rag/rag_implemetation_highflame.ipynb diff --git a/examples/route_examples/aexample.py b/examples/route_examples/aexample.py index 04cf5f8..736f1cd 100644 --- a/examples/route_examples/aexample.py +++ b/examples/route_examples/aexample.py @@ -4,7 +4,7 @@ import dotenv -from javelin_sdk import ( +from highflame_sdk import ( JavelinClient, JavelinConfig, NetworkError, @@ -15,9 +15,14 @@ dotenv.load_dotenv() -# Retrieve environment variables -javelin_api_key = os.getenv("JAVELIN_API_KEY") -javelin_virtualapikey = os.getenv("JAVELIN_VIRTUALAPIKEY") +# Retrieve environment variables (backward compatible: +# check HIGHFLAME_* first, fall back to JAVELIN_*) +javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +) +javelin_virtualapikey = ( + os.getenv("HIGHFLAME_VIRTUALAPIKEY") or os.getenv("JAVELIN_VIRTUALAPIKEY") +) llm_api_key = os.getenv("LLM_API_KEY") @@ -170,7 +175,7 @@ async def main(): try: config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), javelin_api_key=javelin_api_key, javelin_virtualapikey=javelin_virtualapikey, llm_api_key=llm_api_key, diff --git a/examples/route_examples/drop_in_replacement.py b/examples/route_examples/drop_in_replacement.py index b9a1442..91bada0 100644 --- a/examples/route_examples/drop_in_replacement.py +++ b/examples/route_examples/drop_in_replacement.py @@ -3,7 +3,7 @@ import dotenv -from javelin_sdk import ( +from highflame_sdk import ( JavelinClient, JavelinConfig, NetworkError, @@ -14,9 +14,14 @@ dotenv.load_dotenv() -# Retrieve environment variables -javelin_api_key = os.getenv("JAVELIN_API_KEY") -javelin_virtualapikey = os.getenv("JAVELIN_VIRTUALAPIKEY") +# Retrieve environment variables (backward compatible: +# check HIGHFLAME_* first, fall back to JAVELIN_*) +javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +) +javelin_virtualapikey = ( + os.getenv("HIGHFLAME_VIRTUALAPIKEY") or os.getenv("JAVELIN_VIRTUALAPIKEY") +) llm_api_key = os.getenv("OPENAI_API_KEY") @@ -124,7 +129,7 @@ def main(): try: config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), javelin_api_key=javelin_api_key, javelin_virtualapikey=javelin_virtualapikey, llm_api_key=llm_api_key, diff --git a/examples/route_examples/example.py b/examples/route_examples/example.py index 51dc655..da0aa33 100644 --- a/examples/route_examples/example.py +++ b/examples/route_examples/example.py @@ -3,7 +3,7 @@ import dotenv -from javelin_sdk import ( +from highflame_sdk import ( JavelinClient, JavelinConfig, NetworkError, @@ -14,9 +14,14 @@ dotenv.load_dotenv() -# Retrieve environment variables -javelin_api_key = os.getenv("JAVELIN_API_KEY") -javelin_virtualapikey = os.getenv("JAVELIN_VIRTUALAPIKEY") +# Retrieve environment variables (backward compatible: +# check HIGHFLAME_* first, fall back to JAVELIN_*) +javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +) +javelin_virtualapikey = ( + os.getenv("HIGHFLAME_VIRTUALAPIKEY") or os.getenv("JAVELIN_VIRTUALAPIKEY") +) llm_api_key = os.getenv("LLM_API_KEY") @@ -167,7 +172,7 @@ def main(): try: config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), javelin_api_key=javelin_api_key, javelin_virtualapikey=javelin_virtualapikey, llm_api_key=llm_api_key, diff --git a/examples/route_examples/javelin_sdk_app.py b/examples/route_examples/highflame_sdk_app.py similarity index 80% rename from examples/route_examples/javelin_sdk_app.py rename to examples/route_examples/highflame_sdk_app.py index 01becbe..6dc15b4 100644 --- a/examples/route_examples/javelin_sdk_app.py +++ b/examples/route_examples/highflame_sdk_app.py @@ -3,13 +3,18 @@ import dotenv -from javelin_sdk import JavelinClient, JavelinConfig +from highflame_sdk import JavelinClient, JavelinConfig dotenv.load_dotenv() -# Retrieve environment variables -javelin_api_key = os.getenv("JAVELIN_API_KEY") -javelin_virtualapikey = os.getenv("JAVELIN_VIRTUALAPIKEY") +# Retrieve environment variables (backward compatible: +# check HIGHFLAME_* first, fall back to JAVELIN_*) +javelin_api_key = ( + os.getenv("HIGHFLAME_API_KEY") or os.getenv("JAVELIN_API_KEY") +) +javelin_virtualapikey = ( + os.getenv("HIGHFLAME_VIRTUALAPIKEY") or os.getenv("JAVELIN_VIRTUALAPIKEY") +) llm_api_key = os.getenv("LLM_API_KEY") @@ -27,7 +32,7 @@ def pretty_print(obj): def main(): config = JavelinConfig( - base_url=os.getenv("JAVELIN_BASE_URL"), + base_url=os.getenv("HIGHFLAME_BASE_URL") or os.getenv("JAVELIN_BASE_URL"), javelin_api_key=javelin_api_key, javelin_virtualapikey=javelin_virtualapikey, llm_api_key=llm_api_key, diff --git a/javelin_sdk/__init__.py b/highflame/__init__.py similarity index 81% rename from javelin_sdk/__init__.py rename to highflame/__init__.py index aa5b490..4bf1c41 100644 --- a/javelin_sdk/__init__.py +++ b/highflame/__init__.py @@ -1,11 +1,13 @@ -from javelin_sdk.client import JavelinClient -from javelin_sdk.exceptions import ( +from highflame.client import Highflame +from highflame.exceptions import ( BadRequest, + GatewayAlreadyExistsError, GatewayNotFoundError, InternalServerError, MethodNotAllowedError, NetworkError, ProviderAlreadyExistsError, + ProviderNotFoundError, RateLimitExceededError, RouteAlreadyExistsError, RouteNotFoundError, @@ -16,10 +18,10 @@ UnauthorizedError, ValidationError, ) -from javelin_sdk.models import ( +from highflame.models import ( Gateway, Gateways, - JavelinConfig, + Config, Provider, Providers, QueryResponse, @@ -33,7 +35,8 @@ __all__ = [ "GatewayNotFoundError", - "GatewayAlreadyExistsError" "ProviderNotFoundError", + "GatewayAlreadyExistsError", + "ProviderNotFoundError", "ProviderAlreadyExistsError", "RouteNotFoundError", "RouteAlreadyExistsError", @@ -60,6 +63,6 @@ "Secrets", "QueryBody", "QueryResponse", - "JavelinClient", - "JavelinConfig", + "Highflame", + "Config", ] diff --git a/javelin_sdk/chat_completions.py b/highflame/chat_completions.py similarity index 99% rename from javelin_sdk/chat_completions.py rename to highflame/chat_completions.py index 4b01660..ca56b01 100644 --- a/javelin_sdk/chat_completions.py +++ b/highflame/chat_completions.py @@ -1,8 +1,8 @@ import logging from typing import Any, Dict, Generator, List, Optional, Union -from javelin_sdk.model_adapters import ModelTransformer, TransformationRuleManager -from javelin_sdk.models import EndpointType +from highflame.model_adapters import ModelTransformer, TransformationRuleManager +from highflame.models import EndpointType logger = logging.getLogger(__name__) diff --git a/javelin_sdk/client.py b/highflame/client.py similarity index 94% rename from javelin_sdk/client.py rename to highflame/client.py index fba84de..4329456 100644 --- a/javelin_sdk/client.py +++ b/highflame/client.py @@ -1,6 +1,7 @@ import functools import inspect import json +import logging import re import asyncio from typing import Any, Coroutine, Dict, Optional, Union @@ -10,25 +11,27 @@ from opentelemetry.semconv._incubating.attributes import gen_ai_attributes from opentelemetry.trace import SpanKind, Status, StatusCode -from javelin_sdk.chat_completions import Chat, Completions, Embeddings -from javelin_sdk.models import HttpMethod, JavelinConfig, Request -from javelin_sdk.services.gateway_service import GatewayService -from javelin_sdk.services.modelspec_service import ModelSpecService -from javelin_sdk.services.provider_service import ProviderService -from javelin_sdk.services.route_service import RouteService -from javelin_sdk.services.secret_service import SecretService -from javelin_sdk.services.template_service import TemplateService -from javelin_sdk.services.trace_service import TraceService -from javelin_sdk.services.aispm_service import AISPMService -from javelin_sdk.services.guardrails_service import GuardrailsService -from javelin_sdk.tracing_setup import configure_span_exporter - -API_BASEURL = "https://api-dev.javelin.live" +from highflame.chat_completions import Chat, Completions, Embeddings +from highflame.models import HttpMethod, Config, Request +from highflame.services.gateway_service import GatewayService +from highflame.services.modelspec_service import ModelSpecService +from highflame.services.provider_service import ProviderService +from highflame.services.route_service import RouteService +from highflame.services.secret_service import SecretService +from highflame.services.template_service import TemplateService +from highflame.services.trace_service import TraceService +from highflame.services.aispm_service import AISPMService +from highflame.services.guardrails_service import GuardrailsService +from highflame.tracing_setup import configure_span_exporter + +API_BASEURL = "https://api.highflame.app" API_BASE_PATH = "/v1" API_TIMEOUT = 10 +logger = logging.getLogger(__name__) -class JavelinRequestWrapper: + +class RequestWrapper: """A wrapper around Botocore's request object to store additional metadata.""" def __init__(self, original_request, span): @@ -36,7 +39,7 @@ def __init__(self, original_request, span): self.span = span -class JavelinClient: +class Highflame: BEDROCK_RUNTIME_OPERATIONS = frozenset( {"InvokeModel", "InvokeModelWithResponseStream", "Converse", "ConverseStream"} ) @@ -74,15 +77,25 @@ class JavelinClient: "images.create_variation": "image_variation", } - def __init__(self, config: JavelinConfig) -> None: + def __init__(self, config: Config) -> None: self.config = config self.base_url = urljoin(config.base_url, config.api_version or "/v1") - self._headers = {"x-javelin-apikey": config.javelin_api_key} + logger.debug(f"Initializing Highflame client with base_url={self.base_url}") + + # Send both headers for backward compatibility (backend may accept either) + self._headers = { + "x-highflame-apikey": config.api_key, # New header + # Old header (for backward compatibility) + "x-javelin-apikey": config.api_key, + } if config.llm_api_key: self._headers["Authorization"] = f"Bearer {config.llm_api_key}" - if config.javelin_virtualapikey: - self._headers["x-javelin-virtualapikey"] = config.javelin_virtualapikey + if config.virtual_api_key: + # New header + self._headers["x-highflame-virtualapikey"] = config.virtual_api_key + # Old header (for backward compatibility) + self._headers["x-javelin-virtualapikey"] = config.virtual_api_key self._client = None self._aclient = None self.bedrock_client = None @@ -136,13 +149,13 @@ def aclient(self): ) return self._aclient - async def __aenter__(self) -> "JavelinClient": + async def __aenter__(self) -> "Highflame": return self async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: await self.aclose() - def __enter__(self) -> "JavelinClient": + def __enter__(self) -> "Highflame": return self def __exit__(self, exc_type, exc_val, exc_tb) -> None: @@ -184,6 +197,9 @@ def _setup_client_headers(self, openai_client, route_name): openai_client._custom_headers.update(self._headers) if route_name is not None: + # New header + openai_client._custom_headers["x-highflame-route"] = route_name + # Old header (for backward compatibility) openai_client._custom_headers["x-javelin-route"] = route_name # Ensure the client uses the custom headers @@ -274,6 +290,9 @@ def _execute_with_tracing( def _setup_custom_headers(self, openai_client, model): """Setup custom headers for the OpenAI client.""" if model and hasattr(openai_client, "_custom_headers"): + # New header + openai_client._custom_headers["x-highflame-model"] = model + # Old header (for backward compatibility) openai_client._custom_headers["x-javelin-model"] = model if not hasattr(openai_client, "_custom_headers"): @@ -391,7 +410,7 @@ def _capture_response_details(self, span, response, kwargs, system_name): try: response_data = self._extract_response_data(response) if response_data is None: - span.set_attribute("javelin.response.body", str(response)) + span.set_attribute("highflame.response.body", str(response)) return self._set_basic_response_attributes(span, response_data) @@ -400,8 +419,8 @@ def _capture_response_details(self, span, response, kwargs, system_name): self._add_choice_events(span, response_data, system_name) except Exception as e: - span.set_attribute("javelin.response.body", str(response)) - span.set_attribute("javelin.error", str(e)) + span.set_attribute("highflame.response.body", str(response)) + span.set_attribute("highflame.error", str(e)) def _extract_response_data(self, response): """Extract response data from various response types.""" @@ -750,12 +769,12 @@ def _create_bedrock_request_handlers( """Create request handlers for bedrock operations.""" def add_custom_headers(request: Any, **kwargs) -> None: - """Add Javelin headers to each request.""" + """Add Highflame headers to each request.""" request.headers.update(self._headers) def override_endpoint_url(request: Any, **kwargs) -> None: """ - Redirect Bedrock operations to the Javelin endpoint + Redirect Bedrock operations to the Highflame endpoint while preserving path and query. """ try: @@ -764,11 +783,21 @@ def override_endpoint_url(request: Any, **kwargs) -> None: # Construct the base URL (scheme + netloc) base_url = f"{original_url.scheme}://{original_url.netloc}" - # Set the header + # Set the header (dual support for backward compatibility) + # New header + request.headers["x-highflame-provider"] = base_url + # Old header (for backward compatibility) request.headers["x-javelin-provider"] = base_url if self.use_default_bedrock_route and self.default_bedrock_route: - request.headers["x-javelin-route"] = self.default_bedrock_route + # New header + request.headers["x-highflame-route"] = ( + self.default_bedrock_route + ) + # Old header (for backward compatibility) + request.headers["x-javelin-route"] = ( + self.default_bedrock_route + ) path = original_url.path path = unquote(path) @@ -779,9 +808,12 @@ def override_endpoint_url(request: Any, **kwargs) -> None: if model_id: model_id = re.sub(r"-\d{8}(?=-)", "", model_id) + # New header + request.headers["x-highflame-model"] = model_id + # Old header (for backward compatibility) request.headers["x-javelin-model"] = model_id - # Update the request URL to use the Javelin endpoint. + # Update the request URL to use the Highflame endpoint. parsed_base = urlparse(self.base_url) updated_url = original_url._replace( scheme=parsed_base.scheme, @@ -818,7 +850,7 @@ def bedrock_before_call(**kwargs): span = self.tracer.start_span(operation_name, kind=SpanKind.CLIENT) # Store it in the context - context["javelin_request_wrapper"] = JavelinRequestWrapper(None, span) + context["highflame_request_wrapper"] = RequestWrapper(None, span) def bedrock_after_call(**kwargs): """ @@ -828,7 +860,7 @@ def bedrock_after_call(**kwargs): if not context: return - wrapper = context.get("javelin_request_wrapper") + wrapper = context.get("highflame_request_wrapper") if not wrapper: return @@ -917,8 +949,8 @@ def register_bedrock( Example: >>> bedrock = boto3.client('bedrock-runtime') - >>> modified_client = javelin_client.register_bedrock_client(bedrock) - >>> javelin_client.register_bedrock_client(bedrock) + >>> modified_client = highflame_client.register_bedrock_client(bedrock) + >>> highflame_client.register_bedrock_client(bedrock) >>> bedrock.invoke_model( """ self._setup_bedrock_clients( @@ -970,9 +1002,11 @@ def _prepare_request(self, request: Request) -> tuple: if ( request.route and request.route.startswith("v1/admin/aispm") - and "x-javelin-accountid" in headers + and ("x-highflame-accountid" in headers or "x-javelin-accountid" in headers) ): + # Remove both old and new headers for backward compatibility headers.pop("x-javelin-apikey", None) + headers.pop("x-highflame-apikey", None) return url, headers diff --git a/javelin_sdk/exceptions.py b/highflame/exceptions.py similarity index 82% rename from javelin_sdk/exceptions.py rename to highflame/exceptions.py index 965b0e9..2eefbfa 100644 --- a/javelin_sdk/exceptions.py +++ b/highflame/exceptions.py @@ -4,16 +4,16 @@ from pydantic import ValidationError as PydanticValidationError -class JavelinClientError(Exception): +class ClientError(Exception): """ - Base exception class for JavelinClient errors. + Base exception class for Highflame client errors. Attributes ---------- message : str - The error message associated with the JavelinClient error. + The error message associated with the client error. response_data : Optional[dict] - The response data associated with the JavelinClient error. + The response data associated with the client error. Parameters ---------- @@ -59,14 +59,14 @@ def __str__(self): return f"{self.message}: {self.response_data}" -class GatewayNotFoundError(JavelinClientError): +class GatewayNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Gateway not found" ) -> None: super().__init__(message=message, response=response) -class GatewayAlreadyExistsError(JavelinClientError): +class GatewayAlreadyExistsError(ClientError): def __init__( self, response: Optional[Response] = None, @@ -75,28 +75,28 @@ def __init__( super().__init__(message=message, response=response) -class RouteNotFoundError(JavelinClientError): +class RouteNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Route not found" ) -> None: super().__init__(message=message, response=response) -class RouteAlreadyExistsError(JavelinClientError): +class RouteAlreadyExistsError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Route already exists" ) -> None: super().__init__(message=message, response=response) -class ProviderNotFoundError(JavelinClientError): +class ProviderNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Provider not found" ) -> None: super().__init__(message=message, response=response) -class ProviderAlreadyExistsError(JavelinClientError): +class ProviderAlreadyExistsError(ClientError): def __init__( self, response: Optional[Response] = None, @@ -105,21 +105,21 @@ def __init__( super().__init__(message=message, response=response) -class TemplateNotFoundError(JavelinClientError): +class TemplateNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Template not found" ) -> None: super().__init__(message=message, response=response) -class TraceNotFoundError(JavelinClientError): +class TraceNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Trace not found" ) -> None: super().__init__(message=message, response=response) -class TemplateAlreadyExistsError(JavelinClientError): +class TemplateAlreadyExistsError(ClientError): def __init__( self, response: Optional[Response] = None, @@ -128,14 +128,14 @@ def __init__( super().__init__(message=message, response=response) -class SecretNotFoundError(JavelinClientError): +class SecretNotFoundError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Secret not found" ) -> None: super().__init__(message=message, response=response) -class SecretAlreadyExistsError(JavelinClientError): +class SecretAlreadyExistsError(ClientError): def __init__( self, response: Optional[Response] = None, @@ -144,28 +144,28 @@ def __init__( super().__init__(message=message, response=response) -class NetworkError(JavelinClientError): +class NetworkError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Connection error" ) -> None: super().__init__(message=message, response=response) -class BadRequest(JavelinClientError): +class BadRequest(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Bad Request" ) -> None: super().__init__(message=message, response=response) -class RateLimitExceededError(JavelinClientError): +class RateLimitExceededError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Rate limit exceeded" ) -> None: super().__init__(message=message, response=response) -class InternalServerError(JavelinClientError): +class InternalServerError(ClientError): def __init__( self, response: Optional[Response] = None, @@ -174,14 +174,14 @@ def __init__( super().__init__(message=message, response=response) -class MethodNotAllowedError(JavelinClientError): +class MethodNotAllowedError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Method not allowed" ) -> None: super().__init__(message=message, response=response) -class UnauthorizedError(JavelinClientError): +class UnauthorizedError(ClientError): def __init__( self, response: Optional[Response] = None, message: str = "Access denied" ) -> None: @@ -192,7 +192,7 @@ def __str__(self): return self.message -class ValidationError(JavelinClientError): +class ValidationError(ClientError): def __init__( self, error: PydanticValidationError, message: str = "Validation error occurred" ) -> None: diff --git a/javelin_sdk/model_adapters.py b/highflame/model_adapters.py similarity index 100% rename from javelin_sdk/model_adapters.py rename to highflame/model_adapters.py diff --git a/javelin_sdk/models.py b/highflame/models.py similarity index 97% rename from javelin_sdk/models.py rename to highflame/models.py index a070d6c..62138d4 100644 --- a/javelin_sdk/models.py +++ b/highflame/models.py @@ -2,7 +2,7 @@ from enum import Enum, auto from typing import Any, Dict, List, Optional -from javelin_sdk.exceptions import UnauthorizedError +from highflame.exceptions import UnauthorizedError from pydantic import BaseModel, Field, field_validator @@ -465,14 +465,14 @@ class QueryResponse(BaseModel): usage: Usage = Field(..., description="Usage details") -class JavelinConfig(BaseModel): - javelin_api_key: str = Field(..., description="Javelin API key") +class Config(BaseModel): + api_key: str = Field(..., description="Highflame API key") base_url: str = Field( - default="https://api-dev.javelin.live", - description="Base URL for the Javelin API", + default="https://api.highflame.app", + description="Base URL for the Highflame API", ) - javelin_virtualapikey: Optional[str] = Field( - default=None, description="Virtual API key for Javelin" + virtual_api_key: Optional[str] = Field( + default=None, description="Virtual API key for Highflame" ) llm_api_key: Optional[str] = Field( default=None, description="API key for the LLM provider" @@ -485,15 +485,15 @@ class JavelinConfig(BaseModel): default=None, description="Request timeout in seconds" ) - @field_validator("javelin_api_key") + @field_validator("api_key") @classmethod def validate_api_key(cls, value: str) -> str: if not value: raise UnauthorizedError( response=None, message=( - "Please provide a valid Javelin API Key. " - "When you sign into Javelin, you can find your API Key in the " + "Please provide a valid Highflame API Key. " + "When you sign into Highflame, you can find your API Key in the " "Account->Developer settings" ), ) diff --git a/javelin_cli/__init__.py b/highflame/py.typed similarity index 100% rename from javelin_cli/__init__.py rename to highflame/py.typed diff --git a/javelin_sdk/services/aispm_service.py b/highflame/services/aispm_service.py similarity index 90% rename from javelin_sdk/services/aispm_service.py rename to highflame/services/aispm_service.py index 7cbf705..97a750b 100644 --- a/javelin_sdk/services/aispm_service.py +++ b/highflame/services/aispm_service.py @@ -2,7 +2,7 @@ from httpx import Response import json -from javelin_sdk.models import ( +from highflame.models import ( Customer, CustomerResponse, AWSConfig, @@ -23,16 +23,24 @@ def __init__(self, client): def _get_aispm_headers(self) -> Dict[str, str]: """Get headers for AISPM requests, including account_id if available.""" headers = {} - # Check if account_id is stored in client (set by get_javelin_client_aispm) + # Check if account_id is stored in client (set by get_highflame_client_aispm) account_id = getattr(self.client, "_aispm_account_id", None) if account_id: + headers["x-highflame-accountid"] = account_id # New header + # Old header (for backward compatibility) headers["x-javelin-accountid"] = account_id + headers["x-highflame-user"] = getattr( + self.client, "_aispm_user", "test-user" + ) # New header headers["x-javelin-user"] = getattr( self.client, "_aispm_user", "test-user" - ) + ) # Old header (for backward compatibility) + headers["x-highflame-userrole"] = getattr( + self.client, "_aispm_userrole", "org:superadmin" + ) # New header headers["x-javelin-userrole"] = getattr( self.client, "_aispm_userrole", "org:superadmin" - ) + ) # Old header (for backward compatibility) return headers def _handle_response(self, response: Response) -> None: diff --git a/javelin_sdk/services/gateway_service.py b/highflame/services/gateway_service.py similarity index 97% rename from javelin_sdk/services/gateway_service.py rename to highflame/services/gateway_service.py index 5c1143b..d866c27 100644 --- a/javelin_sdk/services/gateway_service.py +++ b/highflame/services/gateway_service.py @@ -1,5 +1,5 @@ import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, GatewayAlreadyExistsError, GatewayNotFoundError, @@ -7,7 +7,7 @@ RateLimitExceededError, UnauthorizedError, ) -from javelin_sdk.models import Gateway, Gateways, HttpMethod, Request +from highflame.models import Gateway, Gateways, HttpMethod, Request class GatewayService: diff --git a/javelin_sdk/services/guardrails_service.py b/highflame/services/guardrails_service.py similarity index 96% rename from javelin_sdk/services/guardrails_service.py rename to highflame/services/guardrails_service.py index eb37370..22a25af 100644 --- a/javelin_sdk/services/guardrails_service.py +++ b/highflame/services/guardrails_service.py @@ -1,11 +1,11 @@ import httpx from typing import Any, Dict, Optional -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, RateLimitExceededError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request +from highflame.models import HttpMethod, Request class GuardrailsService: diff --git a/javelin_sdk/services/modelspec_service.py b/highflame/services/modelspec_service.py similarity index 96% rename from javelin_sdk/services/modelspec_service.py rename to highflame/services/modelspec_service.py index 7a86825..4eabd52 100644 --- a/javelin_sdk/services/modelspec_service.py +++ b/highflame/services/modelspec_service.py @@ -1,13 +1,13 @@ from typing import Any, Dict, Optional import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, InternalServerError, RateLimitExceededError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request +from highflame.models import HttpMethod, Request class ModelSpecService: diff --git a/javelin_sdk/services/provider_service.py b/highflame/services/provider_service.py similarity index 99% rename from javelin_sdk/services/provider_service.py rename to highflame/services/provider_service.py index 467c8ee..effce5d 100644 --- a/javelin_sdk/services/provider_service.py +++ b/highflame/services/provider_service.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Optional import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, InternalServerError, ProviderAlreadyExistsError, @@ -9,7 +9,7 @@ RateLimitExceededError, UnauthorizedError, ) -from javelin_sdk.models import ( +from highflame.models import ( EndpointType, HttpMethod, Provider, diff --git a/javelin_sdk/services/route_service.py b/highflame/services/route_service.py similarity index 97% rename from javelin_sdk/services/route_service.py rename to highflame/services/route_service.py index d9ec620..60979cd 100644 --- a/javelin_sdk/services/route_service.py +++ b/highflame/services/route_service.py @@ -1,8 +1,11 @@ import json +import logging from typing import Any, AsyncGenerator, Dict, Generator, List, Optional, Union import httpx -from javelin_sdk.exceptions import ( +from jsonpath_ng import parse + +from highflame.exceptions import ( BadRequest, InternalServerError, RateLimitExceededError, @@ -10,8 +13,9 @@ RouteNotFoundError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request, Route, Routes, UnivModelConfig -from jsonpath_ng import parse +from highflame.models import HttpMethod, Request, Route, Routes, UnivModelConfig + +logger = logging.getLogger(__name__) class RouteService: @@ -19,12 +23,12 @@ def __init__(self, client): self.client = client def _process_route_response_ok(self, response: httpx.Response) -> str: - """Process a successful response from the Javelin API.""" + """Process a successful response from the Highflame API.""" self._handle_route_response(response) return response.text def _process_route_response(self, response: httpx.Response) -> Route: - """Process a response from the Javelin API and return a Route object.""" + """Process a response from the Highflame API and return a Route object.""" self._handle_route_response(response) return Route(**response.json()) @@ -39,7 +43,7 @@ def _validate_route_name(self, route_name: str): def _process_route_response_json(self, response: httpx.Response) -> Dict[str, Any]: """ - Process a successful response from the Javelin API. + Process a successful response from the Highflame API. Parse body into a Dict[str, Any] object and return it. This is for Query() requests. """ @@ -249,6 +253,7 @@ def query_route( stream_response_path: Optional[str] = None, ) -> Union[Dict[str, Any], Generator[str, None, None]]: """Query a route synchronously.""" + logger.debug(f"Querying route: {route_name}, stream={stream}") self._validate_route_name(route_name) response = self.client._send_request_sync( diff --git a/javelin_sdk/services/secret_service.py b/highflame/services/secret_service.py similarity index 98% rename from javelin_sdk/services/secret_service.py rename to highflame/services/secret_service.py index e12dbcd..ecd750b 100644 --- a/javelin_sdk/services/secret_service.py +++ b/highflame/services/secret_service.py @@ -1,5 +1,5 @@ import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, InternalServerError, RateLimitExceededError, @@ -7,7 +7,7 @@ SecretNotFoundError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request, Secret, Secrets +from highflame.models import HttpMethod, Request, Secret, Secrets class SecretService: diff --git a/javelin_sdk/services/template_service.py b/highflame/services/template_service.py similarity index 98% rename from javelin_sdk/services/template_service.py rename to highflame/services/template_service.py index bce1349..3f9e1e8 100644 --- a/javelin_sdk/services/template_service.py +++ b/highflame/services/template_service.py @@ -1,5 +1,5 @@ import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, InternalServerError, RateLimitExceededError, @@ -7,7 +7,7 @@ TemplateNotFoundError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request, Template, Templates +from highflame.models import HttpMethod, Request, Template, Templates class TemplateService: diff --git a/javelin_sdk/services/trace_service.py b/highflame/services/trace_service.py similarity index 94% rename from javelin_sdk/services/trace_service.py rename to highflame/services/trace_service.py index 486152f..61943a3 100644 --- a/javelin_sdk/services/trace_service.py +++ b/highflame/services/trace_service.py @@ -1,14 +1,14 @@ from typing import Any import httpx -from javelin_sdk.exceptions import ( +from highflame.exceptions import ( BadRequest, InternalServerError, RateLimitExceededError, TraceNotFoundError, UnauthorizedError, ) -from javelin_sdk.models import HttpMethod, Request, Template +from highflame.models import HttpMethod, Request, Template class TraceService: diff --git a/javelin_sdk/tracing_setup.py b/highflame/tracing_setup.py similarity index 82% rename from javelin_sdk/tracing_setup.py rename to highflame/tracing_setup.py index dc77cf4..a7b7025 100644 --- a/javelin_sdk/tracing_setup.py +++ b/highflame/tracing_setup.py @@ -1,17 +1,21 @@ -# javelin_sdk/tracing_setup.py +# highflame/tracing_setup.py # from opentelemetry.instrumentation.botocore import BotocoreInstrumentor +import logging import os from typing import Optional from opentelemetry import trace - # from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter # Use the HTTP exporter instead of the gRPC one -from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.exporter.otlp.proto.http.trace_exporter import ( + OTLPSpanExporter, +) from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor +logger = logging.getLogger(__name__) + # --- OpenTelemetry Setup --- # TRACES_ENDPOINT = os.getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", # "https://api-dev.javelin.live/v1/admin/traces") @@ -22,9 +26,9 @@ TRACES_HEADERS = os.getenv("OTEL_EXPORTER_OTLP_HEADERS") # Initialize OpenTelemetry Tracer -resource = Resource.create({"service.name": "javelin-sdk"}) +resource = Resource.create({"service.name": "highflame"}) trace.set_tracer_provider(TracerProvider(resource=resource)) -tracer = trace.get_tracer("javelin") # Name of the tracer +tracer = trace.get_tracer("highflame") # Name of the tracer def parse_headers(header_str: Optional[str]) -> dict: @@ -47,8 +51,11 @@ def configure_span_exporter(api_key: Optional[str] = None): """ # Disable tracing if TRACES_ENDPOINT is not set if not TRACES_ENDPOINT: + logger.debug("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT not set, tracing disabled") return None + logger.debug(f"Configuring OTLP span exporter with endpoint={TRACES_ENDPOINT}") + # Parse headers from environment variable otlp_headers = parse_headers(TRACES_HEADERS) @@ -58,6 +65,7 @@ def configure_span_exporter(api_key: Optional[str] = None): # Setup OTLP Exporter with API key in headers span_exporter = OTLPSpanExporter(endpoint=TRACES_ENDPOINT, headers=otlp_headers) + logger.debug("OTLP span exporter configured successfully") span_processor = BatchSpanProcessor(span_exporter) provider = trace.get_tracer_provider() diff --git a/javelin_cli/_internal/__init__.py b/highflame_cli/__init__.py similarity index 100% rename from javelin_cli/_internal/__init__.py rename to highflame_cli/__init__.py diff --git a/javelin_cli/__main__.py b/highflame_cli/__main__.py similarity index 100% rename from javelin_cli/__main__.py rename to highflame_cli/__main__.py diff --git a/highflame_cli/_internal/__init__.py b/highflame_cli/_internal/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/javelin_cli/_internal/commands.py b/highflame_cli/_internal/commands.py similarity index 90% rename from javelin_cli/_internal/commands.py rename to highflame_cli/_internal/commands.py index d7fbf1d..91a3133 100644 --- a/javelin_cli/_internal/commands.py +++ b/highflame_cli/_internal/commands.py @@ -1,17 +1,17 @@ import json from pathlib import Path -from javelin_sdk.client import JavelinClient -from javelin_sdk.exceptions import ( +from highflame.client import Highflame +from highflame.exceptions import ( BadRequest, NetworkError, UnauthorizedError, ) -from javelin_sdk.models import ( +from highflame.models import ( AWSConfig, Gateway, GatewayConfig, - JavelinConfig, + Config, Customer, Model, Provider, @@ -27,10 +27,25 @@ from pydantic import ValidationError -def get_javelin_client_aispm(): - # Path to cache.json file +def get_cache_file(): + """Get cache file path, checking new location first, + then falling back to old location""" home_dir = Path.home() - json_file_path = home_dir / ".javelin" / "cache.json" + # Try new location first + new_cache_file = home_dir / ".highflame" / "cache.json" + if new_cache_file.exists(): + return new_cache_file + # Fall back to old location for backward compatibility + old_cache_file = home_dir / ".javelin" / "cache.json" + if old_cache_file.exists(): + return old_cache_file + # Default to new location if neither exists + return new_cache_file + + +def get_highflame_client_aispm(): + # Path to cache.json file + json_file_path = get_cache_file() # Load cache.json if not json_file_path.exists(): @@ -80,15 +95,15 @@ def get_javelin_client_aispm(): except (IndexError, AttributeError): pass - javelin_api_key = selected_gateway.get("api_key_value", "placeholder") + api_key = selected_gateway.get("api_key_value", "placeholder") - # Initialize and return the JavelinClient - config = JavelinConfig( + # Initialize and return the Highflame client + config = Config( base_url=base_url, - javelin_api_key=javelin_api_key, + api_key=api_key, ) - client = JavelinClient(config) + client = Highflame(config) # Store account_id in client for AISPM service to use if account_id: @@ -99,10 +114,9 @@ def get_javelin_client_aispm(): return client -def get_javelin_client(): +def get_highflame_client(): # Path to cache.json file - home_dir = Path.home() - json_file_path = home_dir / ".javelin" / "cache.json" + json_file_path = get_cache_file() # Load cache.json if not json_file_path.exists(): @@ -135,34 +149,34 @@ def get_javelin_client(): selected_gateway = gateways[choice] base_url = selected_gateway["base_url"] - javelin_api_key = selected_gateway["api_key_value"] + api_key = selected_gateway["api_key_value"] # Print all the relevant variables for debugging (optional) # print(f"Base URL: {base_url}") - # print(f"Javelin API Key: {javelin_api_key}") + # print(f"Highflame API Key: {api_key}") # Ensure the API key is set before initializing - if not javelin_api_key or javelin_api_key == "": + if not api_key or api_key == "": raise UnauthorizedError( response=None, message=( - "Please provide a valid Javelin API Key. " - "When you sign into Javelin, you can find your API Key in the " + "Please provide a valid Highflame API Key. " + "When you sign into Highflame, you can find your API Key in the " "Account->Developer settings" ), ) - # Initialize the JavelinClient when required - config = JavelinConfig( + # Initialize the Highflame client when required + config = Config( base_url=base_url, - javelin_api_key=javelin_api_key, + api_key=api_key, ) - return JavelinClient(config) + return Highflame(config) def create_customer(args): - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() customer = Customer( name=args.name, description=args.description, @@ -177,7 +191,7 @@ def get_customer(args): Gets customer details using the AISPM service. """ try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() response = client.aispm.get_customer() # Pretty print the response for CLI output @@ -198,7 +212,7 @@ def get_customer(args): def configure_aws(args): try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() config = json.loads(args.config) configs = [AWSConfig(**config)] client.aispm.configure_aws(configs) @@ -212,7 +226,7 @@ def get_aws_config(args): Gets AWS configurations using the AISPM service. """ try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() response = client.aispm.get_aws_configs() # Simply print the JSON response print(json.dumps(response, indent=2)) @@ -229,7 +243,7 @@ def delete_aws_config(args): Deletes an AWS configuration. """ try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() client.aispm.delete_aws_config(args.name) print(f"AWS configuration '{args.name}' deleted successfully.") except Exception as e: @@ -241,7 +255,7 @@ def get_azure_config(args): Gets Azure configurations using the AISPM service. """ try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() response = client.aispm.get_azure_config() # Format and print the response nicely print(json.dumps(response, indent=2)) @@ -251,7 +265,7 @@ def get_azure_config(args): def configure_azure(args): try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() config = json.loads(args.config) configs = [AzureConfig(**config)] client.aispm.configure_azure(configs) @@ -262,7 +276,7 @@ def configure_azure(args): def get_usage(args): try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() usage = client.aispm.get_usage( provider=args.provider, cloud_account=args.account, @@ -276,7 +290,7 @@ def get_usage(args): def get_alerts(args): try: - client = get_javelin_client_aispm() + client = get_highflame_client_aispm() alerts = client.aispm.get_alerts( provider=args.provider, cloud_account=args.account, @@ -290,7 +304,7 @@ def get_alerts(args): def create_gateway(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON input for GatewayConfig config_data = json.loads(args.config) @@ -313,7 +327,7 @@ def create_gateway(args): def list_gateways(args): """ try: - client = get_javelin_client() + client = get_highflame_client() # Fetch and print the list of gateways gateways = client.list_gateways() @@ -328,8 +342,7 @@ def list_gateways(args): print(f"Unexpected error: {e}") """ # Path to cache.json file - home_dir = Path.home() - json_file_path = home_dir / ".javelin" / "cache.json" + json_file_path = get_cache_file() # Load cache.json if not json_file_path.exists(): @@ -363,7 +376,7 @@ def list_gateways(args): def get_gateway(args): try: - client = get_javelin_client() + client = get_highflame_client() gateway = client.get_gateway(args.name) print(f"Gateway details for '{args.name}':") @@ -379,7 +392,7 @@ def get_gateway(args): def update_gateway(args): try: - client = get_javelin_client() + client = get_highflame_client() config_data = json.loads(args.config) config = GatewayConfig(**config_data) @@ -400,7 +413,7 @@ def update_gateway(args): def delete_gateway(args): try: - client = get_javelin_client() + client = get_highflame_client() client.delete_gateway(args.name) print(f"Gateway '{args.name}' deleted successfully.") @@ -415,7 +428,7 @@ def delete_gateway(args): def create_provider(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string from args.config to a dictionary config_data = json.loads(args.config) @@ -452,7 +465,7 @@ def create_provider(args): def list_providers(args): try: - client = get_javelin_client() + client = get_highflame_client() providers = client.list_providers() print("List of providers:") @@ -468,7 +481,7 @@ def list_providers(args): def get_provider(args): try: - client = get_javelin_client() + client = get_highflame_client() provider = client.get_provider(args.name) print(f"Provider details for '{args.name}':") @@ -484,7 +497,7 @@ def get_provider(args): def update_provider(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string for config config_data = json.loads(args.config) @@ -517,7 +530,7 @@ def update_provider(args): def delete_provider(args): try: - client = get_javelin_client() + client = get_highflame_client() client.delete_provider(args.name) print(f"Provider '{args.name}' deleted successfully.") @@ -532,7 +545,7 @@ def delete_provider(args): def create_route(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string for config and models config_data = json.loads(args.config) @@ -570,7 +583,7 @@ def create_route(args): def list_routes(args): try: - client = get_javelin_client() + client = get_highflame_client() routes = client.list_routes() print("List of routes:") @@ -586,7 +599,7 @@ def list_routes(args): def get_route(args): try: - client = get_javelin_client() + client = get_highflame_client() route = client.get_route(args.name) print(f"Route details for '{args.name}':") @@ -602,7 +615,7 @@ def get_route(args): def update_route(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string for config and models config_data = json.loads(args.config) @@ -636,7 +649,7 @@ def update_route(args): def delete_route(args): try: - client = get_javelin_client() + client = get_highflame_client() client.delete_route(args.name) print(f"Route '{args.name}' deleted successfully.") @@ -651,7 +664,7 @@ def delete_route(args): def create_secret(args): try: - client = get_javelin_client() + client = get_highflame_client() # Create an instance of the Secret class using the provided arguments secret = Secret( @@ -686,7 +699,7 @@ def create_secret(args): def list_secrets(args): try: - client = get_javelin_client() + client = get_highflame_client() # Fetch the list of secrets from the client secrets_response = client.list_secrets() @@ -720,7 +733,7 @@ def list_secrets(args): def get_secret(args): try: - client = get_javelin_client() + client = get_highflame_client() # Fetch the secret and mask sensitive data secret = client.get_secret(args.api_key) @@ -739,7 +752,7 @@ def get_secret(args): def update_secret(args): try: - client = get_javelin_client() + client = get_highflame_client() # Create an instance of the Secret class secret = Secret( @@ -769,7 +782,7 @@ def update_secret(args): def delete_secret(args): try: - client = get_javelin_client() + client = get_highflame_client() client.delete_secret(args.provider_name, args.api_key) print(f"Secret '{args.api_key}' deleted successfully.") @@ -784,7 +797,7 @@ def delete_secret(args): def create_template(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string for config and models config_data = json.loads(args.config) @@ -821,7 +834,7 @@ def create_template(args): def list_templates(args): try: - client = get_javelin_client() + client = get_highflame_client() templates = client.list_templates() print("List of templates:") @@ -837,7 +850,7 @@ def list_templates(args): def get_template(args): try: - client = get_javelin_client() + client = get_highflame_client() template = client.get_template(args.name) print(f"Template details for '{args.name}':") @@ -853,7 +866,7 @@ def get_template(args): def update_template(args): try: - client = get_javelin_client() + client = get_highflame_client() # Parse the JSON string for config and models config_data = json.loads(args.config) @@ -888,7 +901,7 @@ def update_template(args): def delete_template(args): try: - client = get_javelin_client() + client = get_highflame_client() client.delete_template(args.name) print(f"Template '{args.name}' deleted successfully.") diff --git a/javelin_cli/cli.py b/highflame_cli/cli.py similarity index 94% rename from javelin_cli/cli.py rename to highflame_cli/cli.py index f5b984f..2689f5f 100644 --- a/javelin_cli/cli.py +++ b/highflame_cli/cli.py @@ -12,7 +12,7 @@ import requests -from javelin_cli._internal.commands import ( +from highflame_cli._internal.commands import ( create_gateway, create_provider, create_route, @@ -45,17 +45,17 @@ get_alerts, get_aws_config, get_azure_config, - delete_aws_config + delete_aws_config, + get_cache_file, ) def check_permissions(): """Check if user has permissions""" - home_dir = Path.home() - cache_file = home_dir / ".javelin" / "cache.json" + cache_file = get_cache_file() if not cache_file.exists(): - print("❌ Not authenticated. Please run 'javelin auth' first.") + print("❌ Not authenticated. Please run 'highflame-cli auth' first.") sys.exit(1) try: @@ -67,7 +67,7 @@ def check_permissions(): if membership.get("role") == "org:superadmin": return True - print("❌ Permission denied: Javelin CLI requires superadmin privileges.") + print("❌ Permission denied: HighFlame CLI requires superadmin privileges.") print("Please contact your administrator for access.") sys.exit(1) @@ -79,25 +79,25 @@ def check_permissions(): def main(): # Fetch the version dynamically from the package package_version = importlib.metadata.version( - "javelin-sdk" - ) # Replace with your package name + "highflame" + ) parser = argparse.ArgumentParser( - description="The CLI for Javelin.", + description="The CLI for HighFlame.", formatter_class=argparse.RawTextHelpFormatter, epilog=( - "See https://docs.getjavelin.io/docs/javelin-python/cli for more " + "See https://docs.highflame.ai/ for more " "detailed documentation." ), ) parser.add_argument( - "--version", action="version", version=f"Javelin CLI v{package_version}" + "--version", action="version", version=f"HighFlame CLI v{package_version}" ) subparsers = parser.add_subparsers(title="commands", metavar="") # Auth command - auth_parser = subparsers.add_parser("auth", help="Authenticate with Javelin.") + auth_parser = subparsers.add_parser("auth", help="Authenticate with HighFlame.") auth_parser.add_argument( "--force", action="store_true", @@ -493,10 +493,14 @@ def main(): def authenticate(args): home_dir = Path.home() - javelin_dir = home_dir / ".javelin" - cache_file = javelin_dir / "cache.json" + highflame_dir = home_dir / ".highflame" + cache_file = highflame_dir / "cache.json" + + # Also check old location for backward compatibility + old_cache_file = home_dir / ".javelin" / "cache.json" + print(cache_file) - if cache_file.exists() and not args.force: + if (cache_file.exists() or old_cache_file.exists()) and not args.force: print("✅ User is already authenticated!") print("Use --force to re-authenticate and override existing cache.") return @@ -504,8 +508,8 @@ def authenticate(args): default_url = "https://dev.highflame.dev/" print(" O") print(" /|\\") - print(" / \\ ========> Welcome to Javelin! 🚀") - print("\nBefore you can use Javelin, you need to authenticate.") + print(" / \\ ========> Welcome to HighFlame! 🚀") + print("\nBefore you can use HighFlame, you need to authenticate.") print("Press Enter to open the default login URL in your browser...") print(f"Default URL: {default_url}") print("Or enter a new URL (leave blank to use the default): ", end="") @@ -530,7 +534,7 @@ def authenticate(args): if cache_file.exists(): print("✅ Successfully authenticated!") else: - print("⚠️ Failed to retrieve Javelin cache.") + print("⚠️ Failed to retrieve HighFlame cache.") def start_local_server(): @@ -586,10 +590,10 @@ def run_server(): def store_credentials(secrets): home_dir = Path.home() - javelin_dir = home_dir / ".javelin" - javelin_dir.mkdir(exist_ok=True) + highflame_dir = home_dir / ".highflame" + highflame_dir.mkdir(exist_ok=True) - cache_file = javelin_dir / "cache.json" + cache_file = highflame_dir / "cache.json" try: cache_data = json.loads(secrets) diff --git a/pyproject.toml b/pyproject.toml index 5b7ee62..0d140ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,18 +1,20 @@ [tool.poetry] -name = "javelin-sdk" -version = "RELEASE_VERSION" -description = "Python client for Highflame" +name = "highflame" +version = "2.0.0" +description = "Python SDK for Highflame - Enterprise-Scale LLM Gateway" authors = ["Sharath Rajasekar "] readme = "README.md" license = "Apache-2.0" -homepage = "https://getjavelin.com" +homepage = "https://highflame.com" +repository = "https://github.com/highflame-ai/highflame-python" +keywords = ["llm", "gateway", "ai", "api", "routing"] packages = [ - { include = "javelin_cli" }, - { include = "javelin_sdk" }, + { include = "highflame_cli" }, + { include = "highflame" }, ] [tool.poetry.scripts] -javelin = "javelin_cli.cli:main" +highflame-cli = "highflame_cli.cli:main" [tool.poetry.dependencies] python = "^3.9" diff --git a/swagger/README.md b/swagger/README.md index c5dabbe..a050169 100644 --- a/swagger/README.md +++ b/swagger/README.md @@ -1,6 +1,6 @@ # Swagger Model Sync -This directory contains a script (`sync_models.py`) for synchronizing Python models with a Swagger/OpenAPI specification from javelin admin repo. +This directory contains a script (`sync_models.py`) for synchronizing Python models with a Swagger/OpenAPI specification from HighFlame admin repo. ## Purpose diff --git a/swagger/sync_models.py b/swagger/sync_models.py index 48bff68..7218265 100644 --- a/swagger/sync_models.py +++ b/swagger/sync_models.py @@ -8,7 +8,7 @@ SWAGGER_FILE_PATH = Path(os.path.join(os.path.dirname(__file__), "swagger.yaml")) MODELS_FILE_PATH = Path( - os.path.join(os.path.dirname(__file__), "..", "javelin_sdk", "models.py") + os.path.join(os.path.dirname(__file__), "..", "highflame", "models.py") ) FIELDS_TO_EXCLUDE = { @@ -172,10 +172,10 @@ def modify_and_convert_swagger(input_file, output_file): # Add info section with title and version swagger_data["info"] = { - "title": "Javelin Admin API", + "title": "HighFlame Admin API", "version": "1.0", "contact": {}, - "description": "This is the Javelin Admin API", + "description": "This is the HighFlame Admin API", } # Remove 'providername' from '/v1/admin/providers/secrets/keys' path