|
1 | 1 | """QObserva - Unified quantum observability package.""" |
2 | 2 |
|
3 | | -__version__ = "0.1.3" |
4 | | - |
5 | | -# Re-export agent functionality |
6 | | -# The agent package provides 'qobserva' module, but we also use 'qobserva' |
7 | | -# Solution: Import from agent's source directly using importlib |
| 3 | +__version__ = "0.1.4" |
8 | 4 |
|
| 5 | +# In PyPI installs, qobserva-agent and qobserva share the same package namespace. |
| 6 | +# Import directly from the installed namespace package modules. |
9 | 7 | try: |
10 | | - import sys |
11 | | - import importlib |
12 | | - from pathlib import Path |
13 | | - |
14 | | - # Find the agent package's source |
15 | | - current_file = Path(__file__) |
16 | | - packages_dir = current_file.parent.parent.parent |
17 | | - agent_qobserva_dir = packages_dir / "qobserva_agent" / "qobserva" |
18 | | - |
19 | | - if not agent_qobserva_dir.exists(): |
20 | | - raise ImportError(f"Agent directory not found at {agent_qobserva_dir}") |
21 | | - |
22 | | - # Method 1: Try importing from installed agent package |
23 | | - # The agent package installs as 'qobserva' module, but we need to get it |
24 | | - # before our module loads. Since we're already loaded, we need a workaround. |
25 | | - |
26 | | - # Method 2: Load agent's __init__.py directly and execute in isolated namespace |
27 | | - agent_init = agent_qobserva_dir / "__init__.py" |
28 | | - if agent_init.exists(): |
29 | | - # Read and execute the agent's __init__.py in a way that allows imports |
30 | | - import importlib.util |
31 | | - |
32 | | - # Use importlib.machinery for loading |
33 | | - from importlib import machinery |
34 | | - |
35 | | - # We need to set up the module's __package__ and __path__ for relative imports |
36 | | - # But this is complex. Let's try a different approach: |
37 | | - # Import the agent's submodules directly by adding parent to path |
38 | | - |
39 | | - agent_parent = agent_qobserva_dir.parent |
40 | | - saved_path = sys.path[:] |
41 | | - |
42 | | - # Remove any qobserva modules temporarily |
43 | | - saved_modules = {k: v for k, v in sys.modules.items() if k.startswith('qobserva')} |
44 | | - for key in list(saved_modules.keys()): |
45 | | - if key != 'qobserva.qobserva': # Keep our own module |
46 | | - del sys.modules[key] |
47 | | - |
48 | | - sys.path.insert(0, str(agent_parent)) |
49 | | - |
50 | | - try: |
51 | | - # Import agent's qobserva as a different name to avoid conflict |
52 | | - spec = importlib.util.spec_from_file_location( |
53 | | - "agent_qobserva", |
54 | | - agent_init, |
55 | | - submodule_search_locations=[str(agent_qobserva_dir)] |
56 | | - ) |
57 | | - agent_qobserva = importlib.util.module_from_spec(spec) |
58 | | - agent_qobserva.__package__ = "qobserva" |
59 | | - agent_qobserva.__path__ = [str(agent_qobserva_dir)] |
60 | | - spec.loader.exec_module(agent_qobserva) |
61 | | - |
62 | | - observe_run = agent_qobserva.observe_run |
63 | | - QObservaClient = agent_qobserva.QObservaClient |
64 | | - report_run = agent_qobserva.report_run |
65 | | - finally: |
66 | | - sys.path[:] = saved_path |
67 | | - # Restore saved modules except our own |
68 | | - for key, value in saved_modules.items(): |
69 | | - if key != 'qobserva' and not key.startswith('qobserva.qobserva'): |
70 | | - sys.modules[key] = value |
71 | | - else: |
72 | | - raise ImportError(f"Agent __init__.py not found at {agent_init}") |
73 | | - |
74 | | - __all__ = ['observe_run', 'QObservaClient', 'report_run', '__version__'] |
75 | | -except (ImportError, AttributeError, Exception) as import_error: |
76 | | - # Store the error for use in the fallback functions |
| 8 | + from .observe import observe_run |
| 9 | + from .client import QObservaClient |
| 10 | + from .report import report_run |
| 11 | + |
| 12 | + __all__ = ["observe_run", "QObservaClient", "report_run", "__version__"] |
| 13 | +except Exception as import_error: |
77 | 14 | _import_error = import_error |
78 | | - |
79 | | - # If agent is not installed or import fails, provide helpful error |
| 15 | + |
80 | 16 | def observe_run(*args, **kwargs): |
81 | 17 | raise ImportError( |
82 | | - f"qobserva-agent is not installed or cannot be imported.\n" |
83 | | - f"Install it with: pip install -e packages/qobserva_agent\n" |
| 18 | + "qobserva-agent functionality is not available in this installation.\n" |
| 19 | + "Install with: pip install qobserva qobserva-agent\n" |
84 | 20 | f"Original error: {_import_error}" |
85 | 21 | ) |
86 | | - |
87 | | - class QObservaClient: |
| 22 | + |
| 23 | + class QObservaClient: # type: ignore[override] |
88 | 24 | pass |
89 | | - |
| 25 | + |
90 | 26 | def report_run(*args, **kwargs): |
91 | 27 | raise ImportError( |
92 | | - f"qobserva-agent is not installed or cannot be imported.\n" |
93 | | - f"Install it with: pip install -e packages/qobserva_agent\n" |
| 28 | + "qobserva-agent functionality is not available in this installation.\n" |
| 29 | + "Install with: pip install qobserva qobserva-agent\n" |
94 | 30 | f"Original error: {_import_error}" |
95 | 31 | ) |
96 | | - |
97 | | - __all__ = ['observe_run', 'QObservaClient', 'report_run', '__version__'] |
| 32 | + |
| 33 | + __all__ = ["observe_run", "QObservaClient", "report_run", "__version__"] |
0 commit comments