fleet-python 0.1.1__py3-none-any.whl → 0.2.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.

Potentially problematic release.


This version of fleet-python might be problematic. Click here for more details.

fleet/env/factory.py DELETED
@@ -1,337 +0,0 @@
1
- """Fleet SDK Environment Factory."""
2
-
3
- import os
4
- from typing import Dict, Optional, Any, List, Union, Tuple
5
- from datetime import datetime
6
-
7
- from .base import Environment, EnvironmentConfig, RemoteEnvironment
8
- from ..exceptions import FleetEnvironmentError, FleetAuthenticationError
9
- from ..config import get_config, FleetConfig
10
- from ..client import FleetAPIClient, EnvDetails, InstanceRequest
11
-
12
-
13
- # All environment information is now fetched via the Fleet API
14
- # Use list_envs() to get available environments dynamically
15
-
16
-
17
- class InstanceInfo:
18
- """Metadata about a live environment instance."""
19
-
20
- def __init__(
21
- self,
22
- instance_id: str,
23
- env_key: str,
24
- status: str,
25
- created_at: str,
26
- metadata: Optional[Dict[str, Any]] = None
27
- ):
28
- self.instance_id = instance_id
29
- self.env_key = env_key
30
- self.status = status
31
- self.created_at = created_at
32
- self.metadata = metadata or {}
33
-
34
- @property
35
- def version(self) -> Optional[str]:
36
- """Get the environment version."""
37
- return self.metadata.get("version")
38
-
39
- @property
40
- def region(self) -> Optional[str]:
41
- """Get the AWS region."""
42
- return self.metadata.get("region")
43
-
44
- @property
45
- def team_id(self) -> Optional[str]:
46
- """Get the team ID."""
47
- return self.metadata.get("team_id")
48
-
49
- @property
50
- def subdomain(self) -> str:
51
- """Get the subdomain for this instance."""
52
- return f"{self.instance_id}.fleetai.com"
53
-
54
- @property
55
- def health(self) -> Optional[str]:
56
- """Get the health status."""
57
- return self.metadata.get("health")
58
-
59
- def to_dict(self) -> Dict[str, Any]:
60
- """Convert instance to dictionary representation."""
61
- return {
62
- "instance_id": self.instance_id,
63
- "env_key": self.env_key,
64
- "status": self.status,
65
- "created_at": self.created_at,
66
- "metadata": self.metadata,
67
- }
68
-
69
-
70
- def _parse_environment_spec(environment_spec: str) -> Tuple[str, Optional[str]]:
71
- """Parse environment specification into name and version.
72
-
73
- Args:
74
- environment_spec: Environment specification in format:
75
- - "name:version" (e.g., "fira:v1.2.5")
76
- - "name" (defaults to None, will use environment's default version)
77
-
78
- Returns:
79
- Tuple of (name, version)
80
-
81
- Raises:
82
- FleetEnvironmentError: If the specification format is invalid
83
- """
84
- if ":" in environment_spec:
85
- name, version = environment_spec.split(":", 1)
86
- return name, version
87
- else:
88
- return environment_spec, None
89
-
90
-
91
-
92
-
93
-
94
- async def make(
95
- environment_spec: str,
96
- version: Optional[str] = None,
97
- region: Optional[str] = None,
98
- **kwargs: Any,
99
- ) -> Environment:
100
- """Create a Fleet environment.
101
-
102
- Args:
103
- environment_spec: Environment specification in format:
104
- - "name:version" (e.g., "fira:v1.2.5")
105
- - "name" (e.g., "fira" - uses default version)
106
- version: Optional version to override any version in environment_spec
107
- region: Optional AWS region (defaults to "us-west-1")
108
- **kwargs: Additional configuration options
109
-
110
- Returns:
111
- Environment instance
112
-
113
- Raises:
114
- FleetEnvironmentError: If environment specification is invalid
115
- FleetAuthenticationError: If API key is missing or invalid
116
- FleetConfigurationError: If configuration is invalid
117
- """
118
- # Parse the environment specification
119
- env_name, parsed_version = _parse_environment_spec(environment_spec)
120
-
121
- # Use explicit version parameter if provided, otherwise use parsed version
122
- final_version = version or parsed_version
123
-
124
- # Load configuration from environment variables
125
- config = get_config(**kwargs)
126
-
127
- # API key is required
128
- if not config.api_key:
129
- raise FleetAuthenticationError(
130
- "API key is required. Set FLEET_API_KEY environment variable."
131
- )
132
-
133
- # Create environment configuration
134
- env_config = EnvironmentConfig(
135
- environment_type=env_name,
136
- api_key=config.api_key,
137
- base_url=config.base_url,
138
- metadata=kwargs,
139
- )
140
-
141
- # Add version to metadata if specified
142
- if final_version:
143
- env_config.metadata["version"] = final_version
144
-
145
- # Add region to metadata if specified
146
- if region:
147
- env_config.metadata["region"] = region
148
-
149
- # Create API client and create instance
150
- async with FleetAPIClient(config) as client:
151
- try:
152
- # Create instance request
153
- instance_request = InstanceRequest(
154
- env_key=env_name,
155
- version=final_version,
156
- region=region,
157
- **kwargs
158
- )
159
-
160
- # Create the instance
161
- instance_response = await client.create_instance(instance_request)
162
-
163
- # Create environment instance with the created instance
164
- env = RemoteEnvironment(env_config, instance_response=instance_response)
165
-
166
- # Initialize environment
167
- await _initialize_environment(env)
168
-
169
- return env
170
-
171
- except Exception as e:
172
- raise FleetEnvironmentError(f"Failed to create environment instance: {e}")
173
-
174
-
175
- async def get(
176
- instance_id: str,
177
- **kwargs: Any,
178
- ) -> Environment:
179
- """Hydrate an environment from one that is already running.
180
-
181
- Args:
182
- instance_id: ID of the running environment instance to connect to
183
- **kwargs: Additional configuration options
184
-
185
- Returns:
186
- Environment instance connected to the running environment
187
-
188
- Raises:
189
- FleetEnvironmentError: If instance is not found or not accessible
190
- FleetAuthenticationError: If API key is missing or invalid
191
- FleetConfigurationError: If configuration is invalid
192
- """
193
- # Load configuration from environment variables
194
- config = get_config(**kwargs)
195
-
196
- if not config.api_key:
197
- raise FleetAuthenticationError(
198
- "API key is required. Set FLEET_API_KEY environment variable."
199
- )
200
-
201
- # Create API client
202
- async with FleetAPIClient(config) as client:
203
- try:
204
- # Get instance details from API
205
- instance_response = await client.get_instance(instance_id)
206
-
207
- # Create environment configuration based on instance details
208
- env_config = EnvironmentConfig(
209
- environment_type=instance_response.env_key,
210
- api_key=config.api_key,
211
- base_url=config.base_url,
212
- metadata=kwargs,
213
- )
214
-
215
- # Create environment instance with existing instance ID
216
- env = RemoteEnvironment(env_config, instance_id=instance_id)
217
-
218
- # Initialize environment
219
- await _initialize_environment(env)
220
-
221
- return env
222
-
223
- except Exception as e:
224
- raise FleetEnvironmentError(f"Failed to get environment instance {instance_id}: {e}")
225
-
226
-
227
- async def list_instances(
228
- status: Optional[str] = None,
229
- env_key_filter: Optional[str] = None,
230
- **kwargs: Any,
231
- ) -> List[InstanceInfo]:
232
- """Get a directory of all live environment instances.
233
-
234
- Args:
235
- status: Filter by instance status (e.g., 'running', 'paused', 'stopped')
236
- env_key_filter: Filter by environment key (e.g., 'fira', 'dropbox')
237
- **kwargs: Additional query parameters
238
-
239
- Returns:
240
- List of InstanceInfo objects representing live instances
241
-
242
- Raises:
243
- FleetAuthenticationError: If API key is missing or invalid
244
- FleetAPIError: If API request fails
245
- FleetConfigurationError: If configuration is invalid
246
- """
247
- # Load configuration from environment variables
248
- config = get_config(**kwargs)
249
-
250
- if not config.api_key:
251
- raise FleetAuthenticationError(
252
- "API key is required. Set FLEET_API_KEY environment variable."
253
- )
254
-
255
- # Create API client
256
- async with FleetAPIClient(config) as client:
257
- try:
258
- # Get all instances from API
259
- instances = await client.list_instances(status=status)
260
-
261
- # Convert to EnvironmentInstance objects and apply filters
262
- result = []
263
- for instance in instances:
264
- # Apply environment key filter if specified
265
- if env_key_filter and instance.env_key != env_key_filter:
266
- continue
267
-
268
- env_instance = InstanceInfo(
269
- instance_id=instance.instance_id,
270
- env_key=instance.env_key,
271
- status=instance.status,
272
- created_at=instance.created_at,
273
- metadata={
274
- "version": instance.version,
275
- "region": instance.region,
276
- "team_id": instance.team_id,
277
- "urls": instance.urls.model_dump(),
278
- "health": instance.health,
279
- }
280
- )
281
- result.append(env_instance)
282
-
283
- return result
284
-
285
- except Exception as e:
286
- raise FleetEnvironmentError(f"Failed to list instances: {e}")
287
-
288
-
289
- async def list_envs(**kwargs: Any) -> List[EnvDetails]:
290
- """Get list of available environments from Fleet service.
291
-
292
- Args:
293
- **kwargs: Additional query parameters
294
-
295
- Returns:
296
- List of EnvDetails objects with environment details
297
-
298
- Raises:
299
- FleetAuthenticationError: If API key is missing or invalid
300
- FleetAPIError: If API request fails
301
- """
302
- # Load configuration from environment variables
303
- config = get_config(**kwargs)
304
-
305
- if not config.api_key:
306
- raise FleetAuthenticationError(
307
- "API key is required. Set FLEET_API_KEY environment variable."
308
- )
309
-
310
- # Create API client
311
- async with FleetAPIClient(config) as client:
312
- # Get available environments from API - no fallback
313
- environments = await client.list_environments()
314
- return environments
315
-
316
-
317
- # Registry-based functions removed - use API-based list_envs() instead
318
- # All environment information is now fetched dynamically from the Fleet API
319
-
320
-
321
- async def _initialize_environment(env: Environment) -> None:
322
- """Initialize an environment after creation.
323
-
324
- Args:
325
- env: Environment instance to initialize
326
- """
327
- # Perform any necessary initialization
328
- # This could include:
329
- # - Validating API key
330
- # - Setting up HTTP client
331
- # - Registering default facets
332
- # - Performing health checks
333
-
334
- pass
335
-
336
-
337
-
fleet/facets/__init__.py DELETED
@@ -1,7 +0,0 @@
1
- """Fleet SDK Facet Module."""
2
-
3
- from .base import Facet
4
-
5
- __all__ = [
6
- "Facet",
7
- ]
fleet/facets/base.py DELETED
@@ -1,223 +0,0 @@
1
- """Fleet SDK Base Facet Classes."""
2
-
3
- from abc import ABC, abstractmethod
4
- from typing import Any, Dict, Optional, TYPE_CHECKING
5
- from urllib.parse import urlparse
6
-
7
- if TYPE_CHECKING:
8
- from ..env.base import Environment
9
-
10
-
11
- class Facet(ABC):
12
- """Base class for all facets in Fleet environments."""
13
-
14
- def __init__(self, uri: str, environment: "Environment"):
15
- self.uri = uri
16
- self.environment = environment
17
- self._parsed_uri = urlparse(uri)
18
- self._scheme = self._parsed_uri.scheme
19
- self._netloc = self._parsed_uri.netloc
20
- self._path = self._parsed_uri.path
21
- self._params = self._parsed_uri.params
22
- self._query = self._parsed_uri.query
23
- self._fragment = self._parsed_uri.fragment
24
-
25
- @property
26
- def scheme(self) -> str:
27
- """Get the URI scheme (e.g., 'sqlite', 'browser', 'file')."""
28
- return self._scheme
29
-
30
- @property
31
- def netloc(self) -> str:
32
- """Get the URI network location."""
33
- return self._netloc
34
-
35
- @property
36
- def path(self) -> str:
37
- """Get the URI path."""
38
- return self._path
39
-
40
- @abstractmethod
41
- async def initialize(self) -> None:
42
- """Initialize the facet."""
43
- pass
44
-
45
- @abstractmethod
46
- async def close(self) -> None:
47
- """Close the facet and clean up resources."""
48
- pass
49
-
50
- def __repr__(self) -> str:
51
- return f"{self.__class__.__name__}(uri='{self.uri}')"
52
-
53
-
54
- class DatabaseFacet(Facet):
55
- """Base class for database facets."""
56
-
57
- @abstractmethod
58
- async def exec(self, query: str, params: Optional[Dict[str, Any]] = None) -> Any:
59
- """Execute a database query.
60
-
61
- Args:
62
- query: SQL query to execute
63
- params: Query parameters
64
-
65
- Returns:
66
- Query result
67
- """
68
- pass
69
-
70
- @abstractmethod
71
- async def fetch(self, query: str, params: Optional[Dict[str, Any]] = None) -> Any:
72
- """Fetch results from a database query.
73
-
74
- Args:
75
- query: SQL query to execute
76
- params: Query parameters
77
-
78
- Returns:
79
- Query results
80
- """
81
- pass
82
-
83
-
84
- class BrowserFacet(Facet):
85
- """Base class for browser facets."""
86
-
87
- @abstractmethod
88
- async def get_dom(self) -> Dict[str, Any]:
89
- """Get the current DOM structure.
90
-
91
- Returns:
92
- DOM structure as dictionary
93
- """
94
- pass
95
-
96
- @abstractmethod
97
- async def get_element(self, selector: str) -> Optional[Dict[str, Any]]:
98
- """Get an element by CSS selector.
99
-
100
- Args:
101
- selector: CSS selector
102
-
103
- Returns:
104
- Element data or None if not found
105
- """
106
- pass
107
-
108
- @abstractmethod
109
- async def get_elements(self, selector: str) -> list[Dict[str, Any]]:
110
- """Get elements by CSS selector.
111
-
112
- Args:
113
- selector: CSS selector
114
-
115
- Returns:
116
- List of element data
117
- """
118
- pass
119
-
120
-
121
- class FileFacet(Facet):
122
- """Base class for file system facets."""
123
-
124
- @abstractmethod
125
- async def read(self, path: str) -> bytes:
126
- """Read file contents.
127
-
128
- Args:
129
- path: File path
130
-
131
- Returns:
132
- File contents as bytes
133
- """
134
- pass
135
-
136
- @abstractmethod
137
- async def write(self, path: str, content: bytes) -> None:
138
- """Write file contents.
139
-
140
- Args:
141
- path: File path
142
- content: Content to write
143
- """
144
- pass
145
-
146
- @abstractmethod
147
- async def list_dir(self, path: str) -> list[str]:
148
- """List directory contents.
149
-
150
- Args:
151
- path: Directory path
152
-
153
- Returns:
154
- List of file/directory names
155
- """
156
- pass
157
-
158
- @abstractmethod
159
- async def exists(self, path: str) -> bool:
160
- """Check if file or directory exists.
161
-
162
- Args:
163
- path: File or directory path
164
-
165
- Returns:
166
- True if exists, False otherwise
167
- """
168
- pass
169
-
170
-
171
- class APIFacet(Facet):
172
- """Base class for API facets."""
173
-
174
- @abstractmethod
175
- async def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Any:
176
- """Make a GET request.
177
-
178
- Args:
179
- path: API endpoint path
180
- params: Query parameters
181
-
182
- Returns:
183
- API response
184
- """
185
- pass
186
-
187
- @abstractmethod
188
- async def post(self, path: str, data: Optional[Dict[str, Any]] = None) -> Any:
189
- """Make a POST request.
190
-
191
- Args:
192
- path: API endpoint path
193
- data: Request data
194
-
195
- Returns:
196
- API response
197
- """
198
- pass
199
-
200
- @abstractmethod
201
- async def put(self, path: str, data: Optional[Dict[str, Any]] = None) -> Any:
202
- """Make a PUT request.
203
-
204
- Args:
205
- path: API endpoint path
206
- data: Request data
207
-
208
- Returns:
209
- API response
210
- """
211
- pass
212
-
213
- @abstractmethod
214
- async def delete(self, path: str) -> Any:
215
- """Make a DELETE request.
216
-
217
- Args:
218
- path: API endpoint path
219
-
220
- Returns:
221
- API response
222
- """
223
- pass
fleet/facets/factory.py DELETED
@@ -1,29 +0,0 @@
1
- """Fleet SDK Facet Factory."""
2
-
3
- from typing import TYPE_CHECKING
4
- from urllib.parse import urlparse
5
-
6
- from .base import Facet
7
- from ..exceptions import FleetFacetError
8
-
9
- if TYPE_CHECKING:
10
- from ..env.base import Environment
11
-
12
-
13
- def create_facet(uri: str, environment: "Environment") -> Facet:
14
- """Create a facet based on the URI scheme.
15
-
16
- Args:
17
- uri: URI identifying the facet (e.g., 'sqlite://crm', 'browser://dom')
18
- environment: Environment instance
19
-
20
- Returns:
21
- Facet instance
22
-
23
- Raises:
24
- NotImplementedError: Facet implementations are not yet available
25
- """
26
- parsed = urlparse(uri)
27
- scheme = parsed.scheme.lower()
28
-
29
- raise NotImplementedError(f"Facet implementation for scheme '{scheme}' not yet available")