fleet-python 0.2.69b2__tar.gz → 0.2.69b3__tar.gz
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_python-0.2.69b2/fleet_python.egg-info → fleet_python-0.2.69b3}/PKG-INFO +1 -1
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/client.py +20 -9
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3/fleet_python.egg-info}/PKG-INFO +1 -1
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet_python.egg-info/SOURCES.txt +1 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/pyproject.toml +1 -1
- fleet_python-0.2.69b3/tests/test_app_method.py +85 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/LICENSE +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/README.md +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/diff_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/dsl_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/exampleResume.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_account.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_action_log.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_mcp_anthropic.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_mcp_openai.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_sync.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_task.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_tasks.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/example_verifier.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/export_tasks.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/gemini_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/import_tasks.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/json_tasks_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/nova_act_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/openai_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/openai_simple_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/query_builder_example.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/quickstart.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/examples/test_cdp_logging.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/env/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/env/client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/exceptions.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/global_client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/instance/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/instance/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/instance/client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/models.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/resources/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/resources/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/resources/browser.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/resources/mcp.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/resources/sqlite.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/tasks.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/verifiers/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/verifiers/bundler.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/_async/verifiers/verifier.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/config.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/env/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/env/client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/exceptions.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/global_client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/instance/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/instance/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/instance/client.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/instance/models.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/models.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/resources/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/resources/base.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/resources/browser.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/resources/mcp.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/resources/sqlite.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/tasks.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/types.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/bundler.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/code.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/db.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/decorator.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/parse.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/sql_differ.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet/verifiers/verifier.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet_python.egg-info/dependency_links.txt +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet_python.egg-info/requires.txt +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/fleet_python.egg-info/top_level.txt +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/scripts/fix_sync_imports.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/scripts/unasync.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/setup.cfg +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/tests/__init__.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/tests/test_instance_dispatch.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/tests/test_sqlite_resource_dual_mode.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/tests/test_sqlite_shared_memory_behavior.py +0 -0
- {fleet_python-0.2.69b2 → fleet_python-0.2.69b3}/tests/test_verifier_from_string.py +0 -0
|
@@ -22,6 +22,7 @@ import json
|
|
|
22
22
|
import logging
|
|
23
23
|
import os
|
|
24
24
|
from typing import List, Optional, Dict, Any, TYPE_CHECKING, Union
|
|
25
|
+
from urllib.parse import urlparse
|
|
25
26
|
|
|
26
27
|
from .base import EnvironmentBase, SyncWrapper
|
|
27
28
|
from .models import (
|
|
@@ -74,6 +75,14 @@ class SyncEnv(EnvironmentBase):
|
|
|
74
75
|
self._client = client
|
|
75
76
|
self._apps: Dict[str, InstanceClient] = {}
|
|
76
77
|
self._instance: Optional[InstanceClient] = None
|
|
78
|
+
self._manager_url_override: Optional[str] = None # For URL mode
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def manager_url(self) -> str:
|
|
82
|
+
"""Override to support URL mode where urls is None."""
|
|
83
|
+
if self._manager_url_override is not None:
|
|
84
|
+
return self._manager_url_override
|
|
85
|
+
return super().manager_url
|
|
77
86
|
|
|
78
87
|
@property
|
|
79
88
|
def instance(self) -> InstanceClient:
|
|
@@ -85,17 +94,17 @@ class SyncEnv(EnvironmentBase):
|
|
|
85
94
|
|
|
86
95
|
def app(self, name: str) -> InstanceClient:
|
|
87
96
|
if name not in self._apps:
|
|
88
|
-
# Extract
|
|
89
|
-
#
|
|
90
|
-
|
|
91
|
-
#
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
# Extract scheme://netloc from manager_url, then construct /{name}/api/v1/env
|
|
98
|
+
# Supports all URL formats:
|
|
99
|
+
# https://host/api/v1/env -> https://host/{name}/api/v1/env
|
|
100
|
+
# https://host/sentry/api/v1/env -> https://host/{name}/api/v1/env
|
|
101
|
+
# http://localhost:8080/api/v1/env -> http://localhost:8080/{name}/api/v1/env
|
|
102
|
+
parsed = urlparse(self.manager_url)
|
|
103
|
+
root = f"{parsed.scheme}://{parsed.netloc}"
|
|
104
|
+
new_url = f"{root}/{name}/api/v1/env"
|
|
96
105
|
|
|
97
106
|
self._apps[name] = InstanceClient(
|
|
98
|
-
|
|
107
|
+
new_url,
|
|
99
108
|
self._client.httpx_client if self._client else None,
|
|
100
109
|
)
|
|
101
110
|
return self._apps[name]
|
|
@@ -353,6 +362,7 @@ class Fleet:
|
|
|
353
362
|
health=None,
|
|
354
363
|
)
|
|
355
364
|
env._instance = instance_client
|
|
365
|
+
env._manager_url_override = base_url # Set manager_url for URL mode
|
|
356
366
|
return env
|
|
357
367
|
|
|
358
368
|
@staticmethod
|
|
@@ -448,6 +458,7 @@ class Fleet:
|
|
|
448
458
|
health=None,
|
|
449
459
|
)
|
|
450
460
|
env._instance = instance_client
|
|
461
|
+
env._manager_url_override = "local://" # Set manager_url for local mode
|
|
451
462
|
return env
|
|
452
463
|
|
|
453
464
|
def check_bundle_exists(self, bundle_hash: str) -> VerifiersCheckResponse:
|
|
@@ -80,6 +80,7 @@ fleet_python.egg-info/top_level.txt
|
|
|
80
80
|
scripts/fix_sync_imports.py
|
|
81
81
|
scripts/unasync.py
|
|
82
82
|
tests/__init__.py
|
|
83
|
+
tests/test_app_method.py
|
|
83
84
|
tests/test_instance_dispatch.py
|
|
84
85
|
tests/test_sqlite_resource_dual_mode.py
|
|
85
86
|
tests/test_sqlite_shared_memory_behavior.py
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Unit tests for SyncEnv.app() method URL handling."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from unittest.mock import Mock, patch
|
|
5
|
+
from fleet.client import Fleet
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestAppMethod:
|
|
9
|
+
"""Test SyncEnv.app() method with different URL formats."""
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def fleet_client(self):
|
|
13
|
+
"""Create a Fleet client with mocked HTTP client."""
|
|
14
|
+
with patch("fleet.client.default_httpx_client") as mock_client:
|
|
15
|
+
mock_client.return_value = Mock()
|
|
16
|
+
client = Fleet(api_key="test_key")
|
|
17
|
+
client.client.request = Mock()
|
|
18
|
+
return client
|
|
19
|
+
|
|
20
|
+
def test_app_with_existing_app_path(self, fleet_client):
|
|
21
|
+
"""Test app() with URL that already has an app path like /sentry."""
|
|
22
|
+
# Create instance with a URL that has an existing app path
|
|
23
|
+
env = fleet_client.instance("https://example.com/sentry/api/v1/env")
|
|
24
|
+
|
|
25
|
+
# Access jira app
|
|
26
|
+
jira_client = env.app("jira")
|
|
27
|
+
|
|
28
|
+
# Check the constructed URL
|
|
29
|
+
assert jira_client.base_url == "https://example.com/jira/api/v1/env", \
|
|
30
|
+
f"Expected https://example.com/jira/api/v1/env, got {jira_client.base_url}"
|
|
31
|
+
|
|
32
|
+
def test_app_without_app_path(self, fleet_client):
|
|
33
|
+
"""Test app() with URL that has no app path (just /api/v1/env)."""
|
|
34
|
+
# Create instance with a URL without an app path
|
|
35
|
+
env = fleet_client.instance("https://example.com/api/v1/env")
|
|
36
|
+
|
|
37
|
+
# Access jira app
|
|
38
|
+
jira_client = env.app("jira")
|
|
39
|
+
|
|
40
|
+
# Check the constructed URL
|
|
41
|
+
assert jira_client.base_url == "https://example.com/jira/api/v1/env", \
|
|
42
|
+
f"Expected https://example.com/jira/api/v1/env, got {jira_client.base_url}"
|
|
43
|
+
|
|
44
|
+
def test_app_with_different_app_names(self, fleet_client):
|
|
45
|
+
"""Test app() with multiple different app names."""
|
|
46
|
+
env = fleet_client.instance("https://example.com/api/v1/env")
|
|
47
|
+
|
|
48
|
+
jira = env.app("jira")
|
|
49
|
+
sentry = env.app("sentry")
|
|
50
|
+
github = env.app("github")
|
|
51
|
+
|
|
52
|
+
assert jira.base_url == "https://example.com/jira/api/v1/env"
|
|
53
|
+
assert sentry.base_url == "https://example.com/sentry/api/v1/env"
|
|
54
|
+
assert github.base_url == "https://example.com/github/api/v1/env"
|
|
55
|
+
|
|
56
|
+
def test_app_caching(self, fleet_client):
|
|
57
|
+
"""Test that app() caches InstanceClient instances."""
|
|
58
|
+
env = fleet_client.instance("https://example.com/api/v1/env")
|
|
59
|
+
|
|
60
|
+
# Call app("jira") twice
|
|
61
|
+
jira1 = env.app("jira")
|
|
62
|
+
jira2 = env.app("jira")
|
|
63
|
+
|
|
64
|
+
# Should return the same cached instance
|
|
65
|
+
assert jira1 is jira2
|
|
66
|
+
|
|
67
|
+
def test_app_with_localhost(self, fleet_client):
|
|
68
|
+
"""Test app() with localhost URLs."""
|
|
69
|
+
env = fleet_client.instance("http://localhost:8080/api/v1/env")
|
|
70
|
+
|
|
71
|
+
jira = env.app("jira")
|
|
72
|
+
|
|
73
|
+
assert jira.base_url == "http://localhost:8080/jira/api/v1/env"
|
|
74
|
+
|
|
75
|
+
def test_app_with_port(self, fleet_client):
|
|
76
|
+
"""Test app() with URLs that include port numbers."""
|
|
77
|
+
env = fleet_client.instance("https://example.com:9000/api/v1/env")
|
|
78
|
+
|
|
79
|
+
jira = env.app("jira")
|
|
80
|
+
|
|
81
|
+
assert jira.base_url == "https://example.com:9000/jira/api/v1/env"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
if __name__ == "__main__":
|
|
85
|
+
pytest.main([__file__, "-v"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|