haystack-enterprise-sdk 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. haystack_enterprise_sdk/README.md +42 -0
  2. haystack_enterprise_sdk/__init__.py +89 -0
  3. haystack_enterprise_sdk/_api/config.py +135 -0
  4. haystack_enterprise_sdk/_api/deployments.py +726 -0
  5. haystack_enterprise_sdk/_api/files.py +284 -0
  6. haystack_enterprise_sdk/_api/haystack_enterprise_api.py +442 -0
  7. haystack_enterprise_sdk/_api/pipeline_run.py +219 -0
  8. haystack_enterprise_sdk/_api/shared_prototypes.py +127 -0
  9. haystack_enterprise_sdk/_api/upload_sessions.py +293 -0
  10. haystack_enterprise_sdk/_console.py +105 -0
  11. haystack_enterprise_sdk/_s3/__init__.py +1 -0
  12. haystack_enterprise_sdk/_s3/upload.py +394 -0
  13. haystack_enterprise_sdk/_service/deployment_service.py +583 -0
  14. haystack_enterprise_sdk/_service/files_service.py +737 -0
  15. haystack_enterprise_sdk/_service/io_spec.py +203 -0
  16. haystack_enterprise_sdk/_service/pipeline_extract.py +1675 -0
  17. haystack_enterprise_sdk/_service/pipeline_service.py +444 -0
  18. haystack_enterprise_sdk/_service/pipeline_transform.py +575 -0
  19. haystack_enterprise_sdk/_utils/__init__.py +1 -0
  20. haystack_enterprise_sdk/_utils/datetime.py +13 -0
  21. haystack_enterprise_sdk/cli.py +1719 -0
  22. haystack_enterprise_sdk/models.py +293 -0
  23. haystack_enterprise_sdk/workflows/__init__.py +35 -0
  24. haystack_enterprise_sdk/workflows/async_client/__init__.py +1 -0
  25. haystack_enterprise_sdk/workflows/async_client/async_pipeline_client.py +132 -0
  26. haystack_enterprise_sdk/workflows/async_client/deployment_client.py +221 -0
  27. haystack_enterprise_sdk/workflows/async_client/files.py +315 -0
  28. haystack_enterprise_sdk/workflows/sync_client/__init__.py +1 -0
  29. haystack_enterprise_sdk/workflows/sync_client/deployment_client.py +197 -0
  30. haystack_enterprise_sdk/workflows/sync_client/files.py +334 -0
  31. haystack_enterprise_sdk/workflows/sync_client/pipeline_client.py +132 -0
  32. haystack_enterprise_sdk/workflows/sync_client/utils.py +32 -0
  33. haystack_enterprise_sdk-0.1.0.dist-info/METADATA +161 -0
  34. haystack_enterprise_sdk-0.1.0.dist-info/RECORD +37 -0
  35. haystack_enterprise_sdk-0.1.0.dist-info/WHEEL +4 -0
  36. haystack_enterprise_sdk-0.1.0.dist-info/entry_points.txt +3 -0
  37. haystack_enterprise_sdk-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,42 @@
1
+ # Software development kit for the deepset API
2
+
3
+ This package is split into multiple layers:
4
+ - API layer
5
+ - Client layer
6
+ - Service layer
7
+ - Workflow layer
8
+
9
+
10
+ ### API layer
11
+ This layer is the lowest level of abstraction and contains the API definition, including all HTTP methods. It takes care of the authentication.
12
+ You can find this layer in the `haystack_enterprise_sdk/_api/haystack_enterprise_api.py` file. We should implement reties on this lowest layer.
13
+
14
+ ### Client layer
15
+ This layer adds a thin wrapper around the API layer and provides a more convenient interface to the API. It includes explicit methods
16
+ for endpoints by specifying the HTTP methods and endpoints for example for uploading files.
17
+
18
+ ### Service layer
19
+ This layer takes care of combining client methods to provide more complex functionality. Within this layer, we can add functionalities like
20
+ creating sessions, uploading files, and closing sessions.
21
+
22
+ ### Workflow layer
23
+ Public methods for users. These workflows are split into async and sync implementation.
24
+
25
+
26
+ ## Software architecture principles
27
+
28
+ ### Factories
29
+ We are using factories implemented like this:
30
+ ```python
31
+ @classmethod
32
+ async def factory(cls, config: CommonConfig) -> YourClass:
33
+ """Create a new instance of the API client.
34
+
35
+ :param config: CommonConfig object.
36
+ """
37
+ yield cls(config)
38
+ ```
39
+
40
+ ### Tests
41
+ We are using the classical pyramid of tests: unit tests (for each layer), integration tests. The goal is to gradually test each layer and
42
+ then test the whole stack once within the integration tests.
@@ -0,0 +1,89 @@
1
+ """This is the entrypoint for the package."""
2
+
3
+ import logging
4
+
5
+ import structlog
6
+
7
+ from haystack_enterprise_sdk._api.deployments import (
8
+ DeploymentMode,
9
+ DeploymentServiceLevel,
10
+ PipelineValidationError,
11
+ PipelineValidationIssue,
12
+ PipelineValidationResult,
13
+ )
14
+ from haystack_enterprise_sdk._api.pipeline_run import PipelineRunError
15
+ from haystack_enterprise_sdk._api.shared_prototypes import (
16
+ FailedToCreateSharedPrototypeError,
17
+ SharedPrototype,
18
+ )
19
+ from haystack_enterprise_sdk._service.deployment_service import (
20
+ CreateOptions,
21
+ DeploymentFailedError,
22
+ DeployResult,
23
+ ServiceNotFoundError,
24
+ ShareOptions,
25
+ )
26
+ from haystack_enterprise_sdk._service.pipeline_service import (
27
+ ErrorDetail,
28
+ HaystackEnterpriseValidationError,
29
+ )
30
+ from haystack_enterprise_sdk._service.pipeline_transform import (
31
+ PipelineSettings,
32
+ PipelineTransformError,
33
+ )
34
+ from haystack_enterprise_sdk.models import (
35
+ BaseConfig,
36
+ IndexConfig,
37
+ IndexInputs,
38
+ IndexOutputs,
39
+ PipelineConfig,
40
+ PipelineInputs,
41
+ PipelineOutputs,
42
+ PipelineOutputType,
43
+ )
44
+ from haystack_enterprise_sdk.workflows.async_client.async_pipeline_client import (
45
+ AsyncPipelineClient,
46
+ )
47
+ from haystack_enterprise_sdk.workflows.async_client.deployment_client import (
48
+ AsyncDeploymentClient,
49
+ )
50
+ from haystack_enterprise_sdk.workflows.sync_client.deployment_client import DeploymentClient
51
+ from haystack_enterprise_sdk.workflows.sync_client.pipeline_client import PipelineClient
52
+
53
+ structlog.configure(
54
+ wrapper_class=structlog.make_filtering_bound_logger(logging.INFO),
55
+ )
56
+
57
+ log = structlog.get_logger()
58
+
59
+ __all__ = [
60
+ "AsyncPipelineClient",
61
+ "BaseConfig",
62
+ "ErrorDetail",
63
+ "PipelineClient",
64
+ "PipelineConfig",
65
+ "PipelineInputs",
66
+ "PipelineOutputs",
67
+ "IndexConfig",
68
+ "IndexInputs",
69
+ "IndexOutputs",
70
+ "HaystackEnterpriseValidationError",
71
+ "PipelineOutputType",
72
+ "DeploymentClient",
73
+ "AsyncDeploymentClient",
74
+ "CreateOptions",
75
+ "DeploymentMode",
76
+ "DeploymentServiceLevel",
77
+ "DeployResult",
78
+ "ShareOptions",
79
+ "SharedPrototype",
80
+ "DeploymentFailedError",
81
+ "ServiceNotFoundError",
82
+ "FailedToCreateSharedPrototypeError",
83
+ "PipelineSettings",
84
+ "PipelineTransformError",
85
+ "PipelineValidationError",
86
+ "PipelineValidationResult",
87
+ "PipelineValidationIssue",
88
+ "PipelineRunError",
89
+ ]
@@ -0,0 +1,135 @@
1
+ """Config for loading env variables and setting default values."""
2
+
3
+ import os
4
+ import re
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+
8
+ import structlog
9
+ from dotenv import load_dotenv
10
+
11
+ logger = structlog.get_logger(__name__)
12
+
13
+ ENV_FILE_PATH = Path.home() / ".haystack-enterprise" / ".env"
14
+
15
+ # The deepset platform base URL (without a version suffix).
16
+ PLATFORM_URL = "https://api.cloud.deepset.ai"
17
+
18
+ # The API version path appended to the base URL when building requests.
19
+ API_VERSION_PATH = "api/v1"
20
+
21
+ # Matches a trailing version segment like `/api/v1`, `/v1`, `/v2`, ... (case-insensitive),
22
+ # optionally followed by a trailing slash.
23
+ _VERSION_SUFFIX_RE = re.compile(r"/(?:api/)?v\d+/?$", re.IGNORECASE)
24
+
25
+
26
+ def normalize_base_url(url: str) -> str:
27
+ """Normalize an API URL to a bare base URL without a version suffix.
28
+
29
+ Strips a trailing version segment (`/api/v1`, `/v1`, `/v2`, ...) and any trailing slash,
30
+ so both fresh base URLs and legacy full URLs (or pasted URLs including the version) resolve
31
+ to the same base. The SDK appends the version (:data:`API_VERSION_PATH`) when building requests.
32
+
33
+ :param url: The API URL to normalize.
34
+ :return: The base URL without a trailing version segment or slash.
35
+ """
36
+ url = _VERSION_SUFFIX_RE.sub("", url)
37
+ return url.rstrip("/")
38
+
39
+
40
+ def load_environment(show_warnings: bool = True) -> bool:
41
+ """Load environment variables using a cascading fallback model.
42
+
43
+ 1. Load local .env file in current directory if it exists
44
+ 2. Load from global ~/.haystack-enterprise/.env to supplement local .env file
45
+ 3. Environment variables can override both local and global .env files
46
+
47
+ :param show_warnings: Whether to show warnings about missing files/variables
48
+ :return: True if required environment variables were loaded successfully, False otherwise.
49
+ """
50
+ current_path_env = Path.cwd() / ".env"
51
+ local_loaded = current_path_env.is_file() and load_dotenv(current_path_env)
52
+ global_loaded = ENV_FILE_PATH.is_file() and load_dotenv(ENV_FILE_PATH, override=False)
53
+
54
+ # These success messages are gated on ``show_warnings`` so the import-time call
55
+ # (``show_warnings=False``) stays silent, before structlog is even configured.
56
+ if show_warnings:
57
+ if local_loaded:
58
+ logger.info(f"Environment variables successfully loaded from local .env file at {current_path_env}.")
59
+ if global_loaded:
60
+ if local_loaded:
61
+ logger.info(f"Loaded global .env file at {ENV_FILE_PATH} to supplement local .env file.")
62
+ else:
63
+ logger.info(f"Environment variables successfully loaded from global .env file at {ENV_FILE_PATH}.")
64
+
65
+ if not (local_loaded or global_loaded) and show_warnings:
66
+ logger.warning(
67
+ "No .env files found. Run `haystack-enterprise login` to create a global configuration file. "
68
+ "You can also create a custom local .env file in your project directory."
69
+ )
70
+ return False
71
+
72
+ # Check for required environment variables
73
+ required_vars = ["API_KEY", "API_URL", "DEFAULT_WORKSPACE_NAME"]
74
+ missing_vars = [var for var in required_vars if not os.getenv(var)]
75
+
76
+ if missing_vars and show_warnings:
77
+ logger.warning(
78
+ f"Missing required environment variables: {', '.join(missing_vars)}. "
79
+ "Run `haystack-enterprise login` to set up your configuration or set these variables "
80
+ "manually in your .env file."
81
+ )
82
+ return False
83
+
84
+ return True
85
+
86
+
87
+ # Load environment variables silently at import time to support CLI commands that depend on .env files.
88
+ # Warnings are only shown later in CommonConfig when users don't provide explicit parameters
89
+ # and the config values fall back to global defaults.
90
+ load_environment(show_warnings=False)
91
+
92
+ # connection to Haystack Enterprise Platform
93
+ API_URL: str = os.getenv("API_URL", PLATFORM_URL)
94
+
95
+ API_KEY: str = os.getenv("API_KEY", "")
96
+
97
+ # configuration to use a selected workspace
98
+ DEFAULT_WORKSPACE_NAME: str = os.getenv("DEFAULT_WORKSPACE_NAME", "")
99
+
100
+ ASYNC_CLIENT_TIMEOUT: int = int(os.getenv("ASYNC_CLIENT_TIMEOUT", "300"))
101
+
102
+
103
+ @dataclass
104
+ class CommonConfig:
105
+ """Common config for connecting to the Haystack Enterprise Platform.
106
+
107
+ Configuration is loaded in the following order of precedence:
108
+ 1. Explicit parameters passed to this class
109
+ 2. Environment variables
110
+ 3. Local .env file in project root
111
+ 4. Global .env file in ~/.haystack-enterprise/ (supplements local .env)
112
+ 5. Built-in defaults
113
+ """
114
+
115
+ api_key: str = ""
116
+ api_url: str = ""
117
+ safe_mode: bool = False
118
+
119
+ def __post_init__(self) -> None:
120
+ """Validate config."""
121
+ # Only try loading from environment if user didn't provide explicit parameters)
122
+ if not self.api_key or not self.api_url:
123
+ load_environment(show_warnings=True)
124
+ if not self.api_key:
125
+ self.api_key = os.getenv("API_KEY", "")
126
+ if not self.api_url:
127
+ self.api_url = os.getenv("API_URL", PLATFORM_URL)
128
+
129
+ if not self.api_key:
130
+ raise ValueError(
131
+ "API key is required. Either set the API_KEY environment variable or pass api_key parameter. Go to [API Keys](https://cloud.deepset.ai/settings/api-keys) in Haystack Enterprise Platform to get an API key."
132
+ )
133
+
134
+ # Normalize to a bare base URL; the version suffix is appended when building requests.
135
+ self.api_url = normalize_base_url(self.api_url)