optimizely-opal.opal-tools-sdk 0.1.3.dev0__py3-none-any.whl → 0.1.4.dev0__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.
@@ -1,6 +1,7 @@
1
1
  from .service import ToolsService
2
2
  from .decorators import tool
3
3
  from .auth import requires_auth
4
+ from .logging import register_logger_factory
4
5
 
5
6
  __version__ = "0.1.0"
6
- __all__ = ["ToolsService", "tool", "requires_auth"]
7
+ __all__ = ["ToolsService", "tool", "requires_auth", "register_logger_factory"]
@@ -6,8 +6,9 @@ from fastapi import APIRouter, Depends, Header, HTTPException
6
6
  from pydantic import BaseModel
7
7
 
8
8
  from .models import Parameter, ParameterType, AuthRequirement
9
+ from .logging import get_logger
9
10
 
10
- logger = logging.getLogger("opal_tools_sdk")
11
+ logger = get_logger(__name__)
11
12
 
12
13
  def tool(name: str, description: str, auth_requirements: Optional[List[Dict[str, Any]]] = None):
13
14
  """Decorator to register a function as an Opal tool.
@@ -95,9 +96,9 @@ def tool(name: str, description: str, auth_requirements: Optional[List[Dict[str,
95
96
  required=required
96
97
  ))
97
98
 
98
- print(f"Registered parameter: {field_name} of type {param_type.value}, required: {required}")
99
+ logger.info(f"Registered parameter: {field_name} of type {param_type.value}, required: {required}")
99
100
  else:
100
- print(f"Warning: No parameter model found for {name}")
101
+ logger.warning(f"Warning: No parameter model found for {name}")
101
102
 
102
103
  endpoint = f"/tools/{name}"
103
104
 
@@ -112,10 +113,10 @@ def tool(name: str, description: str, auth_requirements: Optional[List[Dict[str,
112
113
  required=auth_req.get("required", True)
113
114
  ))
114
115
 
115
- print(f"Registering tool {name} with endpoint {endpoint}")
116
+ logger.info(f"Registering tool {name} with endpoint {endpoint}")
116
117
 
117
118
  if not _registry.services:
118
- print("No services registered in registry! Make sure to create ToolsService before decorating functions.")
119
+ logger.warning("No services registered in registry! Make sure to create ToolsService before decorating functions.")
119
120
 
120
121
  for service in _registry.services:
121
122
  service.register_tool(
@@ -0,0 +1,37 @@
1
+ import logging
2
+ import sys
3
+ from typing import Optional, Callable
4
+
5
+ # Type alias for a logger factory function
6
+ type LoggerFactory = Callable[[Optional[str]], logging.Logger]
7
+
8
+ # Internal variable to hold a custom logger factory
9
+ _custom_logger_factory: Optional[LoggerFactory] = None
10
+
11
+ def register_logger_factory(factory: LoggerFactory):
12
+ """
13
+ Register a custom logger factory function. This function should accept a name (str or None)
14
+ and return a logger instance (e.g., structlog or standard logger).
15
+ """
16
+ global _custom_logger_factory
17
+ _custom_logger_factory = factory
18
+
19
+ def get_logger(name: str = None) -> logging.Logger:
20
+ """
21
+ Returns a logger configured to output to the console, or uses a registered custom logger factory.
22
+ If no name is provided, uses the root logger.
23
+ """
24
+ if _custom_logger_factory is not None:
25
+ return _custom_logger_factory(name)
26
+ logger = logging.getLogger(name)
27
+ if not logger.handlers:
28
+ handler = logging.StreamHandler(sys.stdout)
29
+ formatter = logging.Formatter(
30
+ fmt='%(asctime)s %(levelname)s [%(name)s] %(message)s',
31
+ datefmt='%Y-%m-%d %H:%M:%S'
32
+ )
33
+ handler.setFormatter(formatter)
34
+ logger.addHandler(handler)
35
+ logger.setLevel(logging.INFO)
36
+ logger.propagate = False
37
+ return logger
opal_tools_sdk/service.py CHANGED
@@ -8,7 +8,7 @@ from pydantic import BaseModel, create_model
8
8
  from .models import Function, Parameter, ParameterType, AuthRequirement
9
9
  from . import _registry
10
10
 
11
- logger = logging.getLogger("opal_tools_sdk")
11
+ logger = logging.getLogger(__name__)
12
12
 
13
13
  class ToolsService:
14
14
  """Main class for managing Opal tools."""
@@ -91,7 +91,7 @@ class ToolsService:
91
91
  endpoint: API endpoint for the tool
92
92
  auth_requirements: List of authentication requirements (optional)
93
93
  """
94
- print(f"Registering tool: {name} with endpoint: {endpoint}")
94
+ logger.info(f"Registering tool: {name} with endpoint: {endpoint}")
95
95
 
96
96
  # Extract auth requirements from handler if decorated with @requires_auth
97
97
  handler_auth_requirements = self._extract_auth_requirements(handler)
@@ -116,7 +116,7 @@ class ToolsService:
116
116
  try:
117
117
  # Parse JSON body
118
118
  body = await request.json()
119
- print(f"Received request for {endpoint} with body: {body}")
119
+ logger.info(f"Received request for {endpoint} with body: {body}")
120
120
 
121
121
  # Parameters should be in the "parameters" key according to the spec
122
122
  # This matches how the tools-mgmt-service calls tools
@@ -124,20 +124,20 @@ class ToolsService:
124
124
  params = body["parameters"]
125
125
  else:
126
126
  # For backward compatibility with direct test calls
127
- print(f"Warning: 'parameters' key not found in request body. Using body directly.")
127
+ logger.warning(f"Warning: 'parameters' key not found in request body. Using body directly.")
128
128
  params = body
129
129
 
130
130
  # Extract auth data if available
131
131
  auth_data = body.get("auth")
132
132
  if auth_data:
133
- print(f"Auth data provided for provider: {auth_data.get('provider', 'unknown')}")
133
+ logger.info(f"Auth data provided for provider: {auth_data.get('provider', 'unknown')}")
134
134
 
135
135
  # Extract environment data if available
136
136
  environment = body.get("environment", {})
137
137
  if environment:
138
- print(f"Environment data provided: {environment}")
138
+ logger.info(f"Environment data provided: {environment}")
139
139
 
140
- print(f"Extracted parameters: {params}")
140
+ logger.info(f"Extracted parameters: {params}")
141
141
 
142
142
  # Get the parameter model from handler's signature
143
143
  sig = inspect.signature(handler)
@@ -166,12 +166,12 @@ class ToolsService:
166
166
 
167
167
  result = await handler(*args, **kwargs)
168
168
 
169
- print(f"Tool {name} returned: {result}")
169
+ logger.info(f"Tool {name} returned: {result}")
170
170
  return result
171
171
  except Exception as e:
172
172
  import traceback
173
- print(f"Error in tool {name}: {str(e)}")
174
- print(traceback.format_exc())
173
+ logger.error(f"Error in tool {name}: {str(e)}")
174
+ logger.error(traceback.format_exc())
175
175
  raise HTTPException(status_code=500, detail=str(e))
176
176
 
177
177
  # Update the route function name and docstring
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optimizely-opal.opal-tools-sdk
3
- Version: 0.1.3.dev0
3
+ Version: 0.1.4.dev0
4
4
  Summary: SDK for creating Opal-compatible tools services
5
5
  Home-page: https://github.com/optimizely/opal-tools-sdk
6
6
  Author: Optimizely
@@ -0,0 +1,11 @@
1
+ opal_tools_sdk/__init__.py,sha256=riYZkv0C1Pgwd3SpE9Zwxs3a1eXa26wrGfY1N1Tdjb4,242
2
+ opal_tools_sdk/_registry.py,sha256=YE3eD4kcS09QDe4RccBYAzXPo9znEU7fblrsB-g3o-Y,67
3
+ opal_tools_sdk/auth.py,sha256=9aMiZv6n6_iu7hQA0sKg4hgNr5DzYFFuP0SWUoZf_Vw,1520
4
+ opal_tools_sdk/decorators.py,sha256=iHal7RElOSCWjqKHIK-Hc4GKOsjuGyUg0_lsQKVQShg,5315
5
+ opal_tools_sdk/logging.py,sha256=krvkhdql2GWh0aCWj5gfqyn5plsyLJ773WzIirK7tkU,1325
6
+ opal_tools_sdk/models.py,sha256=lVumBjEWbKtkRBzwXt7m5uagqinJ6Y96K9a5Uw39yaM,2092
7
+ opal_tools_sdk/service.py,sha256=wVYe40zEZc1ynIkvowD9APU8BFHQ5fdy3j8qlsdZB1U,6965
8
+ optimizely_opal_opal_tools_sdk-0.1.4.dev0.dist-info/METADATA,sha256=3uy9B3LYQM6kJj-D_mtfrTYqCmpogXeKT-cMWE8IySU,4115
9
+ optimizely_opal_opal_tools_sdk-0.1.4.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ optimizely_opal_opal_tools_sdk-0.1.4.dev0.dist-info/top_level.txt,sha256=nCJ5PxF0rgoV6yNJvvuUaZPx4D3EWkl7gpu-6xafH1E,15
11
+ optimizely_opal_opal_tools_sdk-0.1.4.dev0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- opal_tools_sdk/__init__.py,sha256=Eu141xM3QVq1O_BLGZS9m_asU1b_KaOApFtwvaYll6E,170
2
- opal_tools_sdk/_registry.py,sha256=YE3eD4kcS09QDe4RccBYAzXPo9znEU7fblrsB-g3o-Y,67
3
- opal_tools_sdk/auth.py,sha256=9aMiZv6n6_iu7hQA0sKg4hgNr5DzYFFuP0SWUoZf_Vw,1520
4
- opal_tools_sdk/decorators.py,sha256=EE5gjpLRENSZv8cz7wHIIfTCvBh7WqvBaiQtDfMaZig,5268
5
- opal_tools_sdk/models.py,sha256=lVumBjEWbKtkRBzwXt7m5uagqinJ6Y96K9a5Uw39yaM,2092
6
- opal_tools_sdk/service.py,sha256=KBqdBHYJ5wgxky0mSv0NJPbbzVhq4YSafgaTbsndTrE,6914
7
- optimizely_opal_opal_tools_sdk-0.1.3.dev0.dist-info/METADATA,sha256=1pXFL2AInL1gJGBgEwCA5xKu8EoH5pyu0TH_m3y9G8U,4115
8
- optimizely_opal_opal_tools_sdk-0.1.3.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- optimizely_opal_opal_tools_sdk-0.1.3.dev0.dist-info/top_level.txt,sha256=nCJ5PxF0rgoV6yNJvvuUaZPx4D3EWkl7gpu-6xafH1E,15
10
- optimizely_opal_opal_tools_sdk-0.1.3.dev0.dist-info/RECORD,,