touchdesigner-mcp-server 0.4.0-alpha.0 → 0.4.0-alpha.2

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 (82) hide show
  1. package/README.ja.md +4 -4
  2. package/README.md +4 -3
  3. package/dist/cli.js +0 -0
  4. package/dist/gen/endpoints/TouchDesignerAPI.js +1 -1
  5. package/dist/gen/mcp/touchDesignerAPI.zod.js +1 -1
  6. package/dist/index.js +0 -0
  7. package/dist/server/touchDesignerServer.js +1 -1
  8. package/package.json +14 -12
  9. package/td/genHandlers.js +0 -47
  10. package/td/import_modules.py +0 -52
  11. package/td/mcp_webserver_base.tox +0 -0
  12. package/td/modules/mcp/controllers/__init__.py +0 -9
  13. package/td/modules/mcp/controllers/api_controller.py +0 -637
  14. package/td/modules/mcp/controllers/generated_handlers.py +0 -365
  15. package/td/modules/mcp/controllers/openapi_router.py +0 -265
  16. package/td/modules/mcp/services/__init__.py +0 -8
  17. package/td/modules/mcp/services/api_service.py +0 -555
  18. package/td/modules/mcp_webserver_script.py +0 -134
  19. package/td/modules/td_server/.dockerignore +0 -72
  20. package/td/modules/td_server/.openapi-generator/FILES +0 -55
  21. package/td/modules/td_server/.openapi-generator/VERSION +0 -1
  22. package/td/modules/td_server/.openapi-generator-ignore +0 -23
  23. package/td/modules/td_server/.travis.yml +0 -14
  24. package/td/modules/td_server/Dockerfile +0 -16
  25. package/td/modules/td_server/README.md +0 -49
  26. package/td/modules/td_server/git_push.sh +0 -57
  27. package/td/modules/td_server/openapi_server/__init__.py +0 -0
  28. package/td/modules/td_server/openapi_server/__main__.py +0 -19
  29. package/td/modules/td_server/openapi_server/controllers/__init__.py +0 -0
  30. package/td/modules/td_server/openapi_server/controllers/default_controller.py +0 -162
  31. package/td/modules/td_server/openapi_server/controllers/security_controller.py +0 -2
  32. package/td/modules/td_server/openapi_server/encoder.py +0 -19
  33. package/td/modules/td_server/openapi_server/models/__init__.py +0 -33
  34. package/td/modules/td_server/openapi_server/models/base_model.py +0 -68
  35. package/td/modules/td_server/openapi_server/models/create_node200_response.py +0 -125
  36. package/td/modules/td_server/openapi_server/models/create_node200_response_data.py +0 -63
  37. package/td/modules/td_server/openapi_server/models/create_node_request.py +0 -123
  38. package/td/modules/td_server/openapi_server/models/delete_node200_response.py +0 -125
  39. package/td/modules/td_server/openapi_server/models/delete_node200_response_data.py +0 -91
  40. package/td/modules/td_server/openapi_server/models/exec_node_method200_response.py +0 -125
  41. package/td/modules/td_server/openapi_server/models/exec_node_method200_response_data.py +0 -65
  42. package/td/modules/td_server/openapi_server/models/exec_node_method_request.py +0 -153
  43. package/td/modules/td_server/openapi_server/models/exec_node_method_request_args_inner.py +0 -34
  44. package/td/modules/td_server/openapi_server/models/exec_python_script200_response.py +0 -125
  45. package/td/modules/td_server/openapi_server/models/exec_python_script200_response_data.py +0 -65
  46. package/td/modules/td_server/openapi_server/models/exec_python_script200_response_data_result.py +0 -63
  47. package/td/modules/td_server/openapi_server/models/exec_python_script_request.py +0 -65
  48. package/td/modules/td_server/openapi_server/models/get_node_detail200_response.py +0 -125
  49. package/td/modules/td_server/openapi_server/models/get_nodes200_response.py +0 -125
  50. package/td/modules/td_server/openapi_server/models/get_nodes200_response_data.py +0 -65
  51. package/td/modules/td_server/openapi_server/models/get_td_info200_response.py +0 -125
  52. package/td/modules/td_server/openapi_server/models/get_td_info200_response_data.py +0 -155
  53. package/td/modules/td_server/openapi_server/models/get_td_python_class_details200_response.py +0 -125
  54. package/td/modules/td_server/openapi_server/models/get_td_python_classes200_response.py +0 -125
  55. package/td/modules/td_server/openapi_server/models/get_td_python_classes200_response_data.py +0 -63
  56. package/td/modules/td_server/openapi_server/models/td_node.py +0 -175
  57. package/td/modules/td_server/openapi_server/models/td_node_family_type.py +0 -44
  58. package/td/modules/td_server/openapi_server/models/td_python_class_details.py +0 -191
  59. package/td/modules/td_server/openapi_server/models/td_python_class_info.py +0 -127
  60. package/td/modules/td_server/openapi_server/models/td_python_method_info.py +0 -121
  61. package/td/modules/td_server/openapi_server/models/td_python_property_info.py +0 -123
  62. package/td/modules/td_server/openapi_server/models/update_node200_response.py +0 -125
  63. package/td/modules/td_server/openapi_server/models/update_node200_response_data.py +0 -149
  64. package/td/modules/td_server/openapi_server/models/update_node200_response_data_failed_inner.py +0 -91
  65. package/td/modules/td_server/openapi_server/models/update_node_request.py +0 -93
  66. package/td/modules/td_server/openapi_server/openapi/openapi.yaml +0 -975
  67. package/td/modules/td_server/openapi_server/test/__init__.py +0 -16
  68. package/td/modules/td_server/openapi_server/test/test_default_controller.py +0 -201
  69. package/td/modules/td_server/openapi_server/typing_utils.py +0 -30
  70. package/td/modules/td_server/openapi_server/util.py +0 -147
  71. package/td/modules/td_server/requirements.txt +0 -13
  72. package/td/modules/td_server/setup.py +0 -37
  73. package/td/modules/td_server/test-requirements.txt +0 -4
  74. package/td/modules/td_server/tox.ini +0 -11
  75. package/td/modules/utils/config.py +0 -7
  76. package/td/modules/utils/error_handling.py +0 -104
  77. package/td/modules/utils/logging.py +0 -23
  78. package/td/modules/utils/result.py +0 -40
  79. package/td/modules/utils/serialization.py +0 -57
  80. package/td/modules/utils/types.py +0 -33
  81. package/td/modules/utils/utils_logging.py +0 -60
  82. package/td/templates/mcp/api_controller_handlers.mustache +0 -63
@@ -1,16 +0,0 @@
1
- import logging
2
-
3
- import connexion
4
- from flask_testing import TestCase
5
-
6
- from openapi_server.encoder import JSONEncoder
7
-
8
-
9
- class BaseTestCase(TestCase):
10
-
11
- def create_app(self):
12
- logging.getLogger('connexion.operation').setLevel('ERROR')
13
- app = connexion.App(__name__, specification_dir='../openapi/')
14
- app.app.json_encoder = JSONEncoder
15
- app.add_api('openapi.yaml', pythonic_params=True)
16
- return app.app
@@ -1,201 +0,0 @@
1
- import unittest
2
-
3
- from flask import json
4
-
5
- from openapi_server.models.create_node200_response import CreateNode200Response # noqa: E501
6
- from openapi_server.models.create_node_request import CreateNodeRequest # noqa: E501
7
- from openapi_server.models.delete_node200_response import DeleteNode200Response # noqa: E501
8
- from openapi_server.models.exec_node_method200_response import ExecNodeMethod200Response # noqa: E501
9
- from openapi_server.models.exec_node_method_request import ExecNodeMethodRequest # noqa: E501
10
- from openapi_server.models.exec_python_script200_response import ExecPythonScript200Response # noqa: E501
11
- from openapi_server.models.exec_python_script_request import ExecPythonScriptRequest # noqa: E501
12
- from openapi_server.models.get_node_detail200_response import GetNodeDetail200Response # noqa: E501
13
- from openapi_server.models.get_nodes200_response import GetNodes200Response # noqa: E501
14
- from openapi_server.models.get_td_info200_response import GetTdInfo200Response # noqa: E501
15
- from openapi_server.models.get_td_python_class_details200_response import GetTdPythonClassDetails200Response # noqa: E501
16
- from openapi_server.models.get_td_python_classes200_response import GetTdPythonClasses200Response # noqa: E501
17
- from openapi_server.models.update_node200_response import UpdateNode200Response # noqa: E501
18
- from openapi_server.models.update_node_request import UpdateNodeRequest # noqa: E501
19
- from openapi_server.test import BaseTestCase
20
-
21
-
22
- class TestDefaultController(BaseTestCase):
23
- """DefaultController integration test stubs"""
24
-
25
- def test_create_node(self):
26
- """Test case for create_node
27
-
28
- Create a new node
29
- """
30
- create_node_request = openapi_server.CreateNodeRequest()
31
- headers = {
32
- 'Accept': 'application/json',
33
- 'Content-Type': 'application/json',
34
- }
35
- response = self.client.open(
36
- '/api/nodes',
37
- method='POST',
38
- headers=headers,
39
- data=json.dumps(create_node_request),
40
- content_type='application/json')
41
- self.assert200(response,
42
- 'Response body is : ' + response.data.decode('utf-8'))
43
-
44
- def test_delete_node(self):
45
- """Test case for delete_node
46
-
47
- Delete an existing node
48
- """
49
- query_string = [('nodePath', 'node_path_example')]
50
- headers = {
51
- 'Accept': 'application/json',
52
- }
53
- response = self.client.open(
54
- '/api/nodes',
55
- method='DELETE',
56
- headers=headers,
57
- query_string=query_string)
58
- self.assert200(response,
59
- 'Response body is : ' + response.data.decode('utf-8'))
60
-
61
- def test_exec_node_method(self):
62
- """Test case for exec_node_method
63
-
64
- Call a method of the specified node
65
- """
66
- exec_node_method_request = openapi_server.ExecNodeMethodRequest()
67
- headers = {
68
- 'Accept': 'application/json',
69
- 'Content-Type': 'application/json',
70
- }
71
- response = self.client.open(
72
- '/api/td/nodes/exec',
73
- method='POST',
74
- headers=headers,
75
- data=json.dumps(exec_node_method_request),
76
- content_type='application/json')
77
- self.assert200(response,
78
- 'Response body is : ' + response.data.decode('utf-8'))
79
-
80
- def test_exec_python_script(self):
81
- """Test case for exec_python_script
82
-
83
- Execute python code on the server
84
- """
85
- exec_python_script_request = openapi_server.ExecPythonScriptRequest()
86
- headers = {
87
- 'Accept': 'application/json',
88
- 'Content-Type': 'application/json',
89
- }
90
- response = self.client.open(
91
- '/api/td/server/exec',
92
- method='POST',
93
- headers=headers,
94
- data=json.dumps(exec_python_script_request),
95
- content_type='application/json')
96
- self.assert200(response,
97
- 'Response body is : ' + response.data.decode('utf-8'))
98
-
99
- def test_get_node_detail(self):
100
- """Test case for get_node_detail
101
-
102
- Get node detail
103
- """
104
- query_string = [('nodePath', 'node_path_example')]
105
- headers = {
106
- 'Accept': 'application/json',
107
- }
108
- response = self.client.open(
109
- '/api/nodes/detail',
110
- method='GET',
111
- headers=headers,
112
- query_string=query_string)
113
- self.assert200(response,
114
- 'Response body is : ' + response.data.decode('utf-8'))
115
-
116
- def test_get_nodes(self):
117
- """Test case for get_nodes
118
-
119
- Get nodes in the path
120
- """
121
- query_string = [('parentPath', 'parent_path_example'),
122
- ('pattern', '*'),
123
- ('includeProperties', False)]
124
- headers = {
125
- 'Accept': 'application/json',
126
- }
127
- response = self.client.open(
128
- '/api/nodes',
129
- method='GET',
130
- headers=headers,
131
- query_string=query_string)
132
- self.assert200(response,
133
- 'Response body is : ' + response.data.decode('utf-8'))
134
-
135
- def test_get_td_info(self):
136
- """Test case for get_td_info
137
-
138
- Get TouchDesigner information
139
- """
140
- headers = {
141
- 'Accept': 'application/json',
142
- }
143
- response = self.client.open(
144
- '/api/td/server/td',
145
- method='GET',
146
- headers=headers)
147
- self.assert200(response,
148
- 'Response body is : ' + response.data.decode('utf-8'))
149
-
150
- def test_get_td_python_class_details(self):
151
- """Test case for get_td_python_class_details
152
-
153
- Get details of a specific Python class or module
154
- """
155
- headers = {
156
- 'Accept': 'application/json',
157
- }
158
- response = self.client.open(
159
- '/api/td/classes/{class_name}'.format(class_name='class_name_example'),
160
- method='GET',
161
- headers=headers)
162
- self.assert200(response,
163
- 'Response body is : ' + response.data.decode('utf-8'))
164
-
165
- def test_get_td_python_classes(self):
166
- """Test case for get_td_python_classes
167
-
168
- Get a list of Python classes and modules
169
- """
170
- headers = {
171
- 'Accept': 'application/json',
172
- }
173
- response = self.client.open(
174
- '/api/td/classes',
175
- method='GET',
176
- headers=headers)
177
- self.assert200(response,
178
- 'Response body is : ' + response.data.decode('utf-8'))
179
-
180
- def test_update_node(self):
181
- """Test case for update_node
182
-
183
- Update node properties
184
- """
185
- update_node_request = openapi_server.UpdateNodeRequest()
186
- headers = {
187
- 'Accept': 'application/json',
188
- 'Content-Type': 'application/json',
189
- }
190
- response = self.client.open(
191
- '/api/nodes/detail',
192
- method='PATCH',
193
- headers=headers,
194
- data=json.dumps(update_node_request),
195
- content_type='application/json')
196
- self.assert200(response,
197
- 'Response body is : ' + response.data.decode('utf-8'))
198
-
199
-
200
- if __name__ == '__main__':
201
- unittest.main()
@@ -1,30 +0,0 @@
1
- import sys
2
-
3
- if sys.version_info < (3, 7):
4
- import typing
5
-
6
- def is_generic(klass):
7
- """ Determine whether klass is a generic class """
8
- return type(klass) == typing.GenericMeta
9
-
10
- def is_dict(klass):
11
- """ Determine whether klass is a Dict """
12
- return klass.__extra__ == dict
13
-
14
- def is_list(klass):
15
- """ Determine whether klass is a List """
16
- return klass.__extra__ == list
17
-
18
- else:
19
-
20
- def is_generic(klass):
21
- """ Determine whether klass is a generic class """
22
- return hasattr(klass, '__origin__')
23
-
24
- def is_dict(klass):
25
- """ Determine whether klass is a Dict """
26
- return klass.__origin__ == dict
27
-
28
- def is_list(klass):
29
- """ Determine whether klass is a List """
30
- return klass.__origin__ == list
@@ -1,147 +0,0 @@
1
- import datetime
2
-
3
- import typing
4
- from openapi_server import typing_utils
5
-
6
-
7
- def _deserialize(data, klass):
8
- """Deserializes dict, list, str into an object.
9
-
10
- :param data: dict, list or str.
11
- :param klass: class literal, or string of class name.
12
-
13
- :return: object.
14
- """
15
- if data is None:
16
- return None
17
-
18
- if klass in (int, float, str, bool, bytearray):
19
- return _deserialize_primitive(data, klass)
20
- elif klass == object:
21
- return _deserialize_object(data)
22
- elif klass == datetime.date:
23
- return deserialize_date(data)
24
- elif klass == datetime.datetime:
25
- return deserialize_datetime(data)
26
- elif typing_utils.is_generic(klass):
27
- if typing_utils.is_list(klass):
28
- return _deserialize_list(data, klass.__args__[0])
29
- if typing_utils.is_dict(klass):
30
- return _deserialize_dict(data, klass.__args__[1])
31
- else:
32
- return deserialize_model(data, klass)
33
-
34
-
35
- def _deserialize_primitive(data, klass):
36
- """Deserializes to primitive type.
37
-
38
- :param data: data to deserialize.
39
- :param klass: class literal.
40
-
41
- :return: int, long, float, str, bool.
42
- :rtype: int | long | float | str | bool
43
- """
44
- try:
45
- value = klass(data)
46
- except UnicodeEncodeError:
47
- value = data
48
- except TypeError:
49
- value = data
50
- return value
51
-
52
-
53
- def _deserialize_object(value):
54
- """Return an original value.
55
-
56
- :return: object.
57
- """
58
- return value
59
-
60
-
61
- def deserialize_date(string):
62
- """Deserializes string to date.
63
-
64
- :param string: str.
65
- :type string: str
66
- :return: date.
67
- :rtype: date
68
- """
69
- if string is None:
70
- return None
71
-
72
- try:
73
- from dateutil.parser import parse
74
- return parse(string).date()
75
- except ImportError:
76
- return string
77
-
78
-
79
- def deserialize_datetime(string):
80
- """Deserializes string to datetime.
81
-
82
- The string should be in iso8601 datetime format.
83
-
84
- :param string: str.
85
- :type string: str
86
- :return: datetime.
87
- :rtype: datetime
88
- """
89
- if string is None:
90
- return None
91
-
92
- try:
93
- from dateutil.parser import parse
94
- return parse(string)
95
- except ImportError:
96
- return string
97
-
98
-
99
- def deserialize_model(data, klass):
100
- """Deserializes list or dict to model.
101
-
102
- :param data: dict, list.
103
- :type data: dict | list
104
- :param klass: class literal.
105
- :return: model object.
106
- """
107
- instance = klass()
108
-
109
- if not instance.openapi_types:
110
- return data
111
-
112
- for attr, attr_type in instance.openapi_types.items():
113
- if data is not None \
114
- and instance.attribute_map[attr] in data \
115
- and isinstance(data, (list, dict)):
116
- value = data[instance.attribute_map[attr]]
117
- setattr(instance, attr, _deserialize(value, attr_type))
118
-
119
- return instance
120
-
121
-
122
- def _deserialize_list(data, boxed_type):
123
- """Deserializes a list and its elements.
124
-
125
- :param data: list to deserialize.
126
- :type data: list
127
- :param boxed_type: class literal.
128
-
129
- :return: deserialized list.
130
- :rtype: list
131
- """
132
- return [_deserialize(sub_data, boxed_type)
133
- for sub_data in data]
134
-
135
-
136
- def _deserialize_dict(data, boxed_type):
137
- """Deserializes a dict and its elements.
138
-
139
- :param data: dict to deserialize.
140
- :type data: dict
141
- :param boxed_type: class literal.
142
-
143
- :return: deserialized dict.
144
- :rtype: dict
145
- """
146
- return {k: _deserialize(v, boxed_type)
147
- for k, v in data.items() }
@@ -1,13 +0,0 @@
1
- connexion[swagger-ui] >= 2.6.0; python_version>="3.6"
2
- # 2.3 is the last version that supports python 3.4-3.5
3
- connexion[swagger-ui] <= 2.3.0; python_version=="3.5" or python_version=="3.4"
4
- # prevent breaking dependencies from advent of connexion>=3.0
5
- connexion[swagger-ui] <= 2.14.2; python_version>"3.4"
6
- # connexion requires werkzeug but connexion < 2.4.0 does not install werkzeug
7
- # we must peg werkzeug versions below to fix connexion
8
- # https://github.com/zalando/connexion/pull/1044
9
- werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4"
10
- swagger-ui-bundle >= 0.0.2
11
- python_dateutil >= 2.6.0
12
- setuptools >= 21.0.0
13
- Flask == 2.1.1
@@ -1,37 +0,0 @@
1
- import sys
2
- from setuptools import setup, find_packages
3
-
4
- NAME = "openapi_server"
5
- VERSION = "1.0.0"
6
-
7
- # To install the library, run the following
8
- #
9
- # python setup.py install
10
- #
11
- # prerequisite: setuptools
12
- # http://pypi.python.org/pypi/setuptools
13
-
14
- REQUIRES = [
15
- "connexion>=2.0.2",
16
- "swagger-ui-bundle>=0.0.2",
17
- "python_dateutil>=2.6.0"
18
- ]
19
-
20
- setup(
21
- name=NAME,
22
- version=VERSION,
23
- description="TouchDesigner API",
24
- author_email="",
25
- url="",
26
- keywords=["OpenAPI", "TouchDesigner API"],
27
- install_requires=REQUIRES,
28
- packages=find_packages(),
29
- package_data={'': ['openapi/openapi.yaml']},
30
- include_package_data=True,
31
- entry_points={
32
- 'console_scripts': ['openapi_server=openapi_server.__main__:main']},
33
- long_description="""\
34
- OpenAPI schema for generating TouchDesigner API client code
35
- """
36
- )
37
-
@@ -1,4 +0,0 @@
1
- pytest~=7.1.0
2
- pytest-cov>=2.8.1
3
- pytest-randomly>=1.2.3
4
- Flask-Testing==0.8.1
@@ -1,11 +0,0 @@
1
- [tox]
2
- envlist = py3
3
- skipsdist=True
4
-
5
- [testenv]
6
- deps=-r{toxinidir}/requirements.txt
7
- -r{toxinidir}/test-requirements.txt
8
- {toxinidir}
9
-
10
- commands=
11
- pytest --cov=openapi_server
@@ -1,7 +0,0 @@
1
- """
2
- TouchDesigner MCP Web Server Configuration Module
3
- Provides API endpoint definitions and HTTP status code settings
4
- """
5
-
6
- # Enable LogLevel.DEBUG logging
7
- DEBUG = True
@@ -1,104 +0,0 @@
1
- """
2
- Error handling utilities for TouchDesigner MCP Web server
3
- Provides standardized error categorization, formatting, and handling
4
- """
5
-
6
- import functools
7
- import traceback
8
- from enum import Enum
9
- from typing import Callable, Optional, TypeVar
10
-
11
- from utils.logging import log_message
12
- from utils.result import Result, error_result
13
- from utils.types import LogLevel
14
-
15
- T = TypeVar("T")
16
-
17
-
18
- class ErrorCategory(Enum):
19
- """
20
- Error categories for better classification and handling
21
- """
22
-
23
- INTERNAL = "INTERNAL"
24
- VALIDATION = "VALIDATION"
25
- NOT_FOUND = "NOT_FOUND"
26
- PERMISSION = "PERMISSION"
27
- NETWORK = "NETWORK"
28
- EXTERNAL = "EXTERNAL"
29
-
30
- def __str__(self) -> str:
31
- return self.value
32
-
33
-
34
- def categorize_error(exception: Exception) -> ErrorCategory:
35
- """
36
- Categorize an exception based on its type and message
37
-
38
- Args:
39
- exception: The exception to categorize
40
-
41
- Returns:
42
- Appropriate ErrorCategory
43
- """
44
- error_message = str(exception).lower()
45
-
46
- if isinstance(exception, ValueError):
47
- return ErrorCategory.VALIDATION
48
- elif isinstance(exception, FileNotFoundError):
49
- return ErrorCategory.NOT_FOUND
50
- elif "not found" in error_message or "doesn't exist" in error_message:
51
- return ErrorCategory.NOT_FOUND
52
- elif "permission" in error_message or "access denied" in error_message:
53
- return ErrorCategory.PERMISSION
54
- elif "network" in error_message or "connection" in error_message:
55
- return ErrorCategory.NETWORK
56
- elif "external" in error_message or "service unavailable" in error_message:
57
- return ErrorCategory.EXTERNAL
58
-
59
- return ErrorCategory.INTERNAL
60
-
61
-
62
- def format_error(message: str, category: Optional[ErrorCategory] = None) -> str:
63
- """
64
- Format an error message with its category
65
-
66
- Args:
67
- message: The error message
68
- category: Error category (defaults to INTERNAL)
69
-
70
- Returns:
71
- Formatted error message
72
- """
73
- if category is None:
74
- category = ErrorCategory.INTERNAL
75
-
76
- return f"{category}: {message}"
77
-
78
-
79
- def handle_service_errors(func: Callable[..., Result]) -> Callable[..., Result]:
80
- """
81
- Decorator to handle errors in service methods and convert them to Result type
82
-
83
- Args:
84
- func: The service method to decorate
85
-
86
- Returns:
87
- Wrapped function that catches exceptions and returns Result
88
- """
89
-
90
- @functools.wraps(func)
91
- def wrapper(*args, **kwargs) -> Result:
92
- try:
93
- return func(*args, **kwargs)
94
- except Exception as e:
95
- category = categorize_error(e)
96
-
97
- func_name = func.__name__
98
- log_message(f"Error in {func_name}: {str(e)}", LogLevel.ERROR)
99
- log_message(traceback.format_exc(), LogLevel.DEBUG)
100
-
101
- error_message = format_error(str(e), category)
102
- return error_result(error_message, {"errorCategory": category})
103
-
104
- return wrapper
@@ -1,23 +0,0 @@
1
- """
2
- Logging module for TouchDesigner MCP Web server
3
- """
4
-
5
- from datetime import datetime
6
-
7
- from utils.types import LogLevel
8
-
9
- from .config import DEBUG
10
-
11
-
12
- def log_message(message: str, level: LogLevel = LogLevel.INFO) -> None:
13
- """Log a message using the appropriate logging mechanism"""
14
-
15
- if not DEBUG and level == LogLevel.DEBUG:
16
- return
17
-
18
- time_stamp = datetime.now().strftime("%Y%m%d_%H:%M:%S.%f")[
19
- :-3
20
- ] + datetime.now().strftime("%z")
21
- prefix = f"{time_stamp} [{level}]"
22
- full_message = f"{prefix}\t{message}"
23
- print(full_message)
@@ -1,40 +0,0 @@
1
- """
2
- Result pattern utilities for TouchDesigner MCP Web server
3
- Provides utility functions for handling success and failure results
4
- """
5
-
6
- from typing import Any, Dict, Optional
7
-
8
- from .types import Result
9
-
10
-
11
- def success_result(data: Any) -> Result:
12
- """
13
- Create a success result with data
14
-
15
- Args:
16
- data: The success result data
17
-
18
- Returns:
19
- Result dictionary with success flag and data
20
- """
21
- return {"success": True, "data": data, "error": None}
22
-
23
-
24
- def error_result(message: str, metadata: Optional[Dict[str, Any]] = None) -> Result:
25
- """
26
- Create an error result with message and optional metadata
27
-
28
- Args:
29
- message: The error message
30
- metadata: Optional additional error metadata
31
-
32
- Returns:
33
- Result dictionary with error information
34
- """
35
- result = {"success": False,"data": None, "error": message}
36
-
37
- if metadata:
38
- result.update(metadata)
39
-
40
- return result