quraite 0.1.0__py3-none-any.whl → 0.1.2__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 (49) hide show
  1. quraite/__init__.py +3 -3
  2. quraite/adapters/__init__.py +134 -134
  3. quraite/adapters/agno_adapter.py +157 -159
  4. quraite/adapters/base.py +123 -123
  5. quraite/adapters/bedrock_agents_adapter.py +343 -343
  6. quraite/adapters/flowise_adapter.py +275 -275
  7. quraite/adapters/google_adk_adapter.py +211 -209
  8. quraite/adapters/http_adapter.py +255 -239
  9. quraite/adapters/{langgraph_adapter.py → langchain_adapter.py} +305 -304
  10. quraite/adapters/{langgraph_server_adapter.py → langchain_server_adapter.py} +252 -252
  11. quraite/adapters/langflow_adapter.py +192 -192
  12. quraite/adapters/n8n_adapter.py +220 -220
  13. quraite/adapters/openai_agents_adapter.py +267 -269
  14. quraite/adapters/pydantic_ai_adapter.py +307 -312
  15. quraite/adapters/smolagents_adapter.py +148 -152
  16. quraite/logger.py +61 -61
  17. quraite/schema/message.py +91 -91
  18. quraite/schema/response.py +16 -16
  19. quraite/serve/__init__.py +1 -1
  20. quraite/serve/cloudflared.py +210 -210
  21. quraite/serve/local_agent.py +360 -360
  22. quraite/traces/traces_adk_openinference.json +379 -0
  23. quraite/traces/traces_agno_multi_agent.json +669 -0
  24. quraite/traces/traces_agno_openinference.json +321 -0
  25. quraite/traces/traces_crewai_openinference.json +155 -0
  26. quraite/traces/traces_langgraph_openinference.json +349 -0
  27. quraite/traces/traces_langgraph_openinference_multi_agent.json +2705 -0
  28. quraite/traces/traces_langgraph_traceloop.json +510 -0
  29. quraite/traces/traces_openai_agents_multi_agent_1.json +402 -0
  30. quraite/traces/traces_openai_agents_openinference.json +341 -0
  31. quraite/traces/traces_pydantic_openinference.json +286 -0
  32. quraite/traces/traces_pydantic_openinference_multi_agent_1.json +399 -0
  33. quraite/traces/traces_pydantic_openinference_multi_agent_2.json +398 -0
  34. quraite/traces/traces_smol_agents_openinference.json +397 -0
  35. quraite/traces/traces_smol_agents_tool_calling_openinference.json +704 -0
  36. quraite/tracing/__init__.py +25 -24
  37. quraite/tracing/constants.py +15 -16
  38. quraite/tracing/span_exporter.py +101 -115
  39. quraite/tracing/span_processor.py +47 -49
  40. quraite/tracing/tool_extractors.py +309 -290
  41. quraite/tracing/trace.py +564 -564
  42. quraite/tracing/types.py +179 -179
  43. quraite/tracing/utils.py +170 -170
  44. quraite/utils/json_utils.py +269 -269
  45. quraite-0.1.2.dist-info/METADATA +386 -0
  46. quraite-0.1.2.dist-info/RECORD +49 -0
  47. {quraite-0.1.0.dist-info → quraite-0.1.2.dist-info}/WHEEL +1 -1
  48. quraite-0.1.0.dist-info/METADATA +0 -44
  49. quraite-0.1.0.dist-info/RECORD +0 -35
@@ -1,210 +1,210 @@
1
- import os
2
- import platform
3
- import re
4
- import shutil
5
- import stat
6
- import subprocess
7
- import threading
8
- import time
9
- from pathlib import Path
10
- from urllib.request import urlopen
11
-
12
- from quraite.logger import get_logger
13
-
14
- # Cloudflare Tunnel download URLs
15
- CLOUDFLARED_RELEASES_URL = (
16
- "https://github.com/cloudflare/cloudflared/releases/latest/download"
17
- )
18
- PLATFORMS = {
19
- "darwin_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-darwin-amd64",
20
- "darwin_arm64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-darwin-arm64",
21
- "windows_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-windows-amd64.exe",
22
- "linux_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-amd64",
23
- "linux_arm64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-arm64",
24
- "linux_arm": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-arm",
25
- }
26
-
27
- logger = get_logger(__name__)
28
-
29
-
30
- class CloudflaredError(Exception):
31
- """Base exception for cloudflared operations."""
32
-
33
-
34
- class CloudflaredTunnel:
35
- """Represents a Cloudflare Tunnel connection."""
36
-
37
- def __init__(self, public_url: str, process: subprocess.Popen):
38
- self.public_url = public_url
39
- self._process = process
40
-
41
- def disconnect(self):
42
- """Disconnect the tunnel."""
43
- if self._process and self._process.poll() is None:
44
- self._process.terminate()
45
- try:
46
- self._process.wait(timeout=5)
47
- except subprocess.TimeoutExpired:
48
- self._process.kill()
49
-
50
-
51
- def get_system() -> str:
52
- """Get the system platform identifier."""
53
- system = platform.system().lower()
54
- machine = platform.machine().lower()
55
-
56
- if system == "darwin":
57
- if machine in ("arm64", "aarch64"):
58
- return "darwin_arm64"
59
- return "darwin_x86_64"
60
- elif system == "windows":
61
- return "windows_x86_64"
62
- elif system == "linux":
63
- if machine in ("arm64", "aarch64"):
64
- return "linux_arm64"
65
- elif machine.startswith("arm"):
66
- return "linux_arm"
67
- return "linux_x86_64"
68
- else:
69
- raise CloudflaredError(f"Unsupported platform: {system} {machine}")
70
-
71
-
72
- def get_cloudflared_path() -> Path:
73
- """Get the path where cloudflared binary should be stored."""
74
- user_home = Path.home()
75
- system = platform.system().lower()
76
-
77
- if system == "darwin":
78
- config_dir = user_home / "Library" / "Application Support" / "cloudflared"
79
- elif system == "windows":
80
- config_dir = user_home / "AppData" / "Local" / "cloudflared"
81
- else:
82
- config_dir = (
83
- Path(os.environ.get("XDG_CONFIG_HOME", user_home / ".config"))
84
- / "cloudflared"
85
- )
86
-
87
- config_dir.mkdir(parents=True, exist_ok=True)
88
-
89
- if system == "windows":
90
- return config_dir / "cloudflared.exe"
91
- return config_dir / "cloudflared"
92
-
93
-
94
- def download_cloudflared(force: bool = False) -> Path:
95
- """
96
- Download cloudflared binary for the current platform.
97
-
98
- Args:
99
- force: If True, re-download even if binary exists
100
-
101
- Returns:
102
- Path to the cloudflared binary
103
- """
104
- # Check if cloudflared is already in PATH
105
- cloudflared_cmd = (
106
- "cloudflared.exe" if platform.system() == "windows" else "cloudflared"
107
- )
108
- if shutil.which(cloudflared_cmd) and not force:
109
- return Path(shutil.which(cloudflared_cmd))
110
-
111
- cloudflared_path = get_cloudflared_path()
112
- system_key = get_system()
113
-
114
- if cloudflared_path.exists() and not force:
115
- # Check if binary is executable
116
- if platform.system() != "windows":
117
- st = os.stat(cloudflared_path)
118
- os.chmod(cloudflared_path, st.st_mode | stat.S_IEXEC)
119
- return cloudflared_path
120
-
121
- if system_key not in PLATFORMS:
122
- raise CloudflaredError(f"Unsupported platform: {system_key}")
123
-
124
- download_url = PLATFORMS[system_key]
125
- logger.info("Downloading cloudflared from %s...", download_url)
126
-
127
- try:
128
- with urlopen(download_url, timeout=30) as response:
129
- with open(cloudflared_path, "wb") as f:
130
- f.write(response.read())
131
-
132
- # Make executable on Unix systems
133
- if platform.system() != "windows":
134
- st = os.stat(cloudflared_path)
135
- os.chmod(cloudflared_path, st.st_mode | stat.S_IEXEC)
136
-
137
- logger.info("Downloaded cloudflared to %s", cloudflared_path)
138
- return cloudflared_path
139
-
140
- except Exception as e:
141
- raise CloudflaredError(f"Failed to download cloudflared: {e}") from e
142
-
143
-
144
- def connect(port: int, host: str = "localhost") -> CloudflaredTunnel:
145
- """
146
- Create a Cloudflare Tunnel connection to the specified port.
147
-
148
- Args:
149
- port: Local port to tunnel
150
- host: Local host (default: localhost)
151
-
152
- Returns:
153
- CloudflaredTunnel object with public_url attribute
154
- """
155
- cloudflared_path = download_cloudflared()
156
-
157
- # Start cloudflared tunnel
158
- cmd = [
159
- str(cloudflared_path),
160
- "tunnel",
161
- "--url",
162
- f"http://{host}:{port}",
163
- ]
164
-
165
- process = subprocess.Popen(
166
- cmd,
167
- stdout=subprocess.PIPE,
168
- stderr=subprocess.STDOUT,
169
- text=True,
170
- bufsize=1,
171
- )
172
-
173
- # Parse output to get public URL
174
- public_url = None
175
- url_pattern = re.compile(r"https://[a-zA-Z0-9-]+\.trycloudflare\.com")
176
-
177
- def read_output():
178
- nonlocal public_url
179
- try:
180
- for line in process.stdout:
181
- if not line:
182
- continue
183
- line = line.strip()
184
- if line:
185
- logger.debug("[cloudflared] %s", line)
186
- # Look for URL in the line
187
- match = url_pattern.search(line)
188
- if match:
189
- public_url = match.group(0)
190
- break
191
- except Exception as e:
192
- logger.error("[cloudflared] Error reading output: %s", e)
193
-
194
- # Start reading output in a separate thread
195
- output_thread = threading.Thread(target=read_output, daemon=True)
196
- output_thread.start()
197
-
198
- # Wait for URL to be available (max 30 seconds)
199
- timeout = 30
200
- start_time = time.time()
201
- while public_url is None and (time.time() - start_time) < timeout:
202
- if process.poll() is not None:
203
- raise CloudflaredError("cloudflared process exited unexpectedly")
204
- time.sleep(0.1)
205
-
206
- if public_url is None:
207
- process.terminate()
208
- raise CloudflaredError("Failed to get public URL from cloudflared")
209
-
210
- return CloudflaredTunnel(public_url=public_url, process=process)
1
+ import os
2
+ import platform
3
+ import re
4
+ import shutil
5
+ import stat
6
+ import subprocess
7
+ import threading
8
+ import time
9
+ from pathlib import Path
10
+ from urllib.request import urlopen
11
+
12
+ from quraite.logger import get_logger
13
+
14
+ # Cloudflare Tunnel download URLs
15
+ CLOUDFLARED_RELEASES_URL = (
16
+ "https://github.com/cloudflare/cloudflared/releases/latest/download"
17
+ )
18
+ PLATFORMS = {
19
+ "darwin_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-darwin-amd64",
20
+ "darwin_arm64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-darwin-arm64",
21
+ "windows_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-windows-amd64.exe",
22
+ "linux_x86_64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-amd64",
23
+ "linux_arm64": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-arm64",
24
+ "linux_arm": f"{CLOUDFLARED_RELEASES_URL}/cloudflared-linux-arm",
25
+ }
26
+
27
+ logger = get_logger(__name__)
28
+
29
+
30
+ class CloudflaredError(Exception):
31
+ """Base exception for cloudflared operations."""
32
+
33
+
34
+ class CloudflaredTunnel:
35
+ """Represents a Cloudflare Tunnel connection."""
36
+
37
+ def __init__(self, public_url: str, process: subprocess.Popen):
38
+ self.public_url = public_url
39
+ self._process = process
40
+
41
+ def disconnect(self):
42
+ """Disconnect the tunnel."""
43
+ if self._process and self._process.poll() is None:
44
+ self._process.terminate()
45
+ try:
46
+ self._process.wait(timeout=5)
47
+ except subprocess.TimeoutExpired:
48
+ self._process.kill()
49
+
50
+
51
+ def get_system() -> str:
52
+ """Get the system platform identifier."""
53
+ system = platform.system().lower()
54
+ machine = platform.machine().lower()
55
+
56
+ if system == "darwin":
57
+ if machine in ("arm64", "aarch64"):
58
+ return "darwin_arm64"
59
+ return "darwin_x86_64"
60
+ elif system == "windows":
61
+ return "windows_x86_64"
62
+ elif system == "linux":
63
+ if machine in ("arm64", "aarch64"):
64
+ return "linux_arm64"
65
+ elif machine.startswith("arm"):
66
+ return "linux_arm"
67
+ return "linux_x86_64"
68
+ else:
69
+ raise CloudflaredError(f"Unsupported platform: {system} {machine}")
70
+
71
+
72
+ def get_cloudflared_path() -> Path:
73
+ """Get the path where cloudflared binary should be stored."""
74
+ user_home = Path.home()
75
+ system = platform.system().lower()
76
+
77
+ if system == "darwin":
78
+ config_dir = user_home / "Library" / "Application Support" / "cloudflared"
79
+ elif system == "windows":
80
+ config_dir = user_home / "AppData" / "Local" / "cloudflared"
81
+ else:
82
+ config_dir = (
83
+ Path(os.environ.get("XDG_CONFIG_HOME", user_home / ".config"))
84
+ / "cloudflared"
85
+ )
86
+
87
+ config_dir.mkdir(parents=True, exist_ok=True)
88
+
89
+ if system == "windows":
90
+ return config_dir / "cloudflared.exe"
91
+ return config_dir / "cloudflared"
92
+
93
+
94
+ def download_cloudflared(force: bool = False) -> Path:
95
+ """
96
+ Download cloudflared binary for the current platform.
97
+
98
+ Args:
99
+ force: If True, re-download even if binary exists
100
+
101
+ Returns:
102
+ Path to the cloudflared binary
103
+ """
104
+ # Check if cloudflared is already in PATH
105
+ cloudflared_cmd = (
106
+ "cloudflared.exe" if platform.system() == "windows" else "cloudflared"
107
+ )
108
+ if shutil.which(cloudflared_cmd) and not force:
109
+ return Path(shutil.which(cloudflared_cmd))
110
+
111
+ cloudflared_path = get_cloudflared_path()
112
+ system_key = get_system()
113
+
114
+ if cloudflared_path.exists() and not force:
115
+ # Check if binary is executable
116
+ if platform.system() != "windows":
117
+ st = os.stat(cloudflared_path)
118
+ os.chmod(cloudflared_path, st.st_mode | stat.S_IEXEC)
119
+ return cloudflared_path
120
+
121
+ if system_key not in PLATFORMS:
122
+ raise CloudflaredError(f"Unsupported platform: {system_key}")
123
+
124
+ download_url = PLATFORMS[system_key]
125
+ logger.info("Downloading cloudflared from %s...", download_url)
126
+
127
+ try:
128
+ with urlopen(download_url, timeout=30) as response:
129
+ with open(cloudflared_path, "wb") as f:
130
+ f.write(response.read())
131
+
132
+ # Make executable on Unix systems
133
+ if platform.system() != "windows":
134
+ st = os.stat(cloudflared_path)
135
+ os.chmod(cloudflared_path, st.st_mode | stat.S_IEXEC)
136
+
137
+ logger.info("Downloaded cloudflared to %s", cloudflared_path)
138
+ return cloudflared_path
139
+
140
+ except Exception as e:
141
+ raise CloudflaredError(f"Failed to download cloudflared: {e}") from e
142
+
143
+
144
+ def connect(port: int, host: str = "localhost") -> CloudflaredTunnel:
145
+ """
146
+ Create a Cloudflare Tunnel connection to the specified port.
147
+
148
+ Args:
149
+ port: Local port to tunnel
150
+ host: Local host (default: localhost)
151
+
152
+ Returns:
153
+ CloudflaredTunnel object with public_url attribute
154
+ """
155
+ cloudflared_path = download_cloudflared()
156
+
157
+ # Start cloudflared tunnel
158
+ cmd = [
159
+ str(cloudflared_path),
160
+ "tunnel",
161
+ "--url",
162
+ f"http://{host}:{port}",
163
+ ]
164
+
165
+ process = subprocess.Popen(
166
+ cmd,
167
+ stdout=subprocess.PIPE,
168
+ stderr=subprocess.STDOUT,
169
+ text=True,
170
+ bufsize=1,
171
+ )
172
+
173
+ # Parse output to get public URL
174
+ public_url = None
175
+ url_pattern = re.compile(r"https://[a-zA-Z0-9-]+\.trycloudflare\.com")
176
+
177
+ def read_output():
178
+ nonlocal public_url
179
+ try:
180
+ for line in process.stdout:
181
+ if not line:
182
+ continue
183
+ line = line.strip()
184
+ if line:
185
+ logger.debug("[cloudflared] %s", line)
186
+ # Look for URL in the line
187
+ match = url_pattern.search(line)
188
+ if match:
189
+ public_url = match.group(0)
190
+ break
191
+ except Exception as e:
192
+ logger.error("[cloudflared] Error reading output: %s", e)
193
+
194
+ # Start reading output in a separate thread
195
+ output_thread = threading.Thread(target=read_output, daemon=True)
196
+ output_thread.start()
197
+
198
+ # Wait for URL to be available (max 30 seconds)
199
+ timeout = 30
200
+ start_time = time.time()
201
+ while public_url is None and (time.time() - start_time) < timeout:
202
+ if process.poll() is not None:
203
+ raise CloudflaredError("cloudflared process exited unexpectedly")
204
+ time.sleep(0.1)
205
+
206
+ if public_url is None:
207
+ process.terminate()
208
+ raise CloudflaredError("Failed to get public URL from cloudflared")
209
+
210
+ return CloudflaredTunnel(public_url=public_url, process=process)