dify_plugin 0.4.2b1__tar.gz → 0.4.2b2__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.
Files changed (146) hide show
  1. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/PKG-INFO +1 -1
  2. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/config/integration_config.py +1 -1
  3. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/plugin/request.py +10 -0
  4. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/plugin_executor.py +17 -1
  5. dify_plugin-0.4.2b2/dify_plugin/entities/oauth.py +35 -0
  6. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/errors/tool.py +4 -0
  7. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/integration/run.py +9 -0
  8. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/tool/__init__.py +54 -6
  9. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/plugin.py +6 -0
  10. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/protocol/oauth.py +18 -1
  11. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/pyproject.toml +1 -1
  12. dify_plugin-0.4.2b1/dify_plugin/entities/oauth.py +0 -17
  13. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/LICENSE +0 -0
  14. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/README.md +0 -0
  15. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/__init__.py +0 -0
  16. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/cli.py +0 -0
  17. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/commands/__init__.py +0 -0
  18. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/commands/generate_docs.py +0 -0
  19. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/config/__init__.py +0 -0
  20. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/config/config.py +0 -0
  21. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/config/logger_format.py +0 -0
  22. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/__init__.py +0 -0
  23. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/documentation/__init__.py +0 -0
  24. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/documentation/generator.py +0 -0
  25. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/documentation/schema_doc.py +0 -0
  26. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/__init__.py +0 -0
  27. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/invocation.py +0 -0
  28. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/message.py +0 -0
  29. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/plugin/__init__.py +0 -0
  30. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/plugin/io.py +0 -0
  31. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/plugin/parameter_type.py +0 -0
  32. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/entities/plugin/setup.py +0 -0
  33. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/plugin_registration.py +0 -0
  34. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/runtime.py +0 -0
  35. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__base/__init__.py +0 -0
  36. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__base/filter_reader.py +0 -0
  37. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__base/request_reader.py +0 -0
  38. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__base/response_writer.py +0 -0
  39. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__base/writer_entities.py +0 -0
  40. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/__init__.py +0 -0
  41. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/io_server.py +0 -0
  42. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/router.py +0 -0
  43. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/serverless/__init__.py +0 -0
  44. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/serverless/request_reader.py +0 -0
  45. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/serverless/response_writer.py +0 -0
  46. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/stdio/__init__.py +0 -0
  47. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/stdio/request_reader.py +0 -0
  48. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/stdio/response_writer.py +0 -0
  49. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/tcp/__init__.py +0 -0
  50. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/server/tcp/request_reader.py +0 -0
  51. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/utils/__init__.py +0 -0
  52. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/utils/class_loader.py +0 -0
  53. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/utils/http_parser.py +0 -0
  54. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/utils/position_helper.py +0 -0
  55. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/core/utils/yaml_loader.py +0 -0
  56. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/__init__.py +0 -0
  57. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/agent.py +0 -0
  58. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/endpoint.py +0 -0
  59. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/invoke_message.py +0 -0
  60. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/__init__.py +0 -0
  61. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/llm.py +0 -0
  62. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/message.py +0 -0
  63. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/moderation.py +0 -0
  64. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/provider.py +0 -0
  65. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/rerank.py +0 -0
  66. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/speech2text.py +0 -0
  67. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/text_embedding.py +0 -0
  68. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/model/tts.py +0 -0
  69. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/provider_config.py +0 -0
  70. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/tool.py +0 -0
  71. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/entities/workflow_node.py +0 -0
  72. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/errors/__init__.py +0 -0
  73. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/errors/model.py +0 -0
  74. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/file/__init__.py +0 -0
  75. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/file/constants.py +0 -0
  76. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/file/entities.py +0 -0
  77. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/file/file.py +0 -0
  78. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/integration/entities.py +0 -0
  79. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/integration/exc.py +0 -0
  80. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/__init__.py +0 -0
  81. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/agent/__init__.py +0 -0
  82. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/endpoint/__init__.py +0 -0
  83. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/__init__.py +0 -0
  84. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/ai_model.py +0 -0
  85. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/audio.mp3 +0 -0
  86. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/large_language_model.py +0 -0
  87. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/moderation_model.py +0 -0
  88. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/__init__.py +0 -0
  89. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/common.py +0 -0
  90. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/llm.py +0 -0
  91. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/provider.py +0 -0
  92. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/rerank.py +0 -0
  93. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/speech2text.py +0 -0
  94. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/text_embedding.py +0 -0
  95. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/openai_compatible/tts.py +0 -0
  96. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/rerank_model.py +0 -0
  97. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/speech2text_model.py +0 -0
  98. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/text_embedding_model.py +0 -0
  99. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/model/tts_model.py +0 -0
  100. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/interfaces/trigger/__init__.py +0 -0
  101. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/__init__.py +0 -0
  102. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/app/__init__.py +0 -0
  103. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/app/chat.py +0 -0
  104. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/app/completion.py +0 -0
  105. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/app/workflow.py +0 -0
  106. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/file.py +0 -0
  107. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/__init__.py +0 -0
  108. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/llm.py +0 -0
  109. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/llm_structured_output.py +0 -0
  110. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/moderation.py +0 -0
  111. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/rerank.py +0 -0
  112. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/speech2text.py +0 -0
  113. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/text_embedding.py +0 -0
  114. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/model/tts.py +0 -0
  115. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/storage.py +0 -0
  116. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/tool.py +0 -0
  117. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/workflow_node/__init__.py +0 -0
  118. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/workflow_node/parameter_extractor.py +0 -0
  119. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/invocations/workflow_node/question_classifier.py +0 -0
  120. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/protocol/__init__.py +0 -0
  121. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/protocol/dynamic_select.py +0 -0
  122. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/tool/__init__.py +0 -0
  123. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/dify_plugin/tool/entities.py +0 -0
  124. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/__init__.py +0 -0
  125. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/__mock_server/__init__.py +0 -0
  126. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/__mock_server/openai.py +0 -0
  127. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/config/test_config.py +0 -0
  128. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/consts/mockserver.py +0 -0
  129. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/entities/endpoint/test_endpoint_group.py +0 -0
  130. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/entities/models/test_llm.py +0 -0
  131. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/entities/plugin/test_declaration.py +0 -0
  132. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/integration/test_invoke_llm.py +0 -0
  133. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/agent/test_agent.py +0 -0
  134. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/model/__init__.py +0 -0
  135. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/model/openai_compatible/__init__.py +0 -0
  136. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/model/openai_compatible/test_increase_tool_call.py +0 -0
  137. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/tool/__init__.py +0 -0
  138. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/tool/test_construct_tool_provider.py +0 -0
  139. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/interfaces/tool/test_costruct_tool.py +0 -0
  140. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/invocations/test_storage.py +0 -0
  141. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/servers/test_session.py +0 -0
  142. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/servers/test_stdio.py +0 -0
  143. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/test_llm_result.py +0 -0
  144. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/test_prompt_message.py +0 -0
  145. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/test_tool_call_model_init.py +0 -0
  146. {dify_plugin-0.4.2b1 → dify_plugin-0.4.2b2}/tests/utils/test_http_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dify_plugin
3
- Version: 0.4.2b1
3
+ Version: 0.4.2b2
4
4
  Summary: Dify Plugin SDK
5
5
  Keywords: dify,plugin,sdk
6
6
  Author-Email: langgenius <hello@dify.ai>
@@ -52,4 +52,4 @@ class IntegrationConfig(BaseSettings):
52
52
 
53
53
  return v
54
54
 
55
- model_config = SettingsConfigDict(env_file=".env")
55
+ model_config = SettingsConfigDict(env_file=".env", extra="allow")
@@ -58,6 +58,7 @@ class EndpointActions(StrEnum):
58
58
  class OAuthActions(StrEnum):
59
59
  GetAuthorizationUrl = "get_authorization_url"
60
60
  GetCredentials = "get_credentials"
61
+ RefreshCredentials = "refresh_credentials"
61
62
 
62
63
 
63
64
  class DynamicParameterActions(StrEnum):
@@ -260,6 +261,15 @@ class OAuthGetCredentialsRequest(PluginAccessRequest):
260
261
  raw_http_request: str
261
262
 
262
263
 
264
+ class OAuthRefreshCredentialsRequest(PluginAccessRequest):
265
+ type: PluginInvokeType = PluginInvokeType.OAuth
266
+ action: OAuthActions = OAuthActions.RefreshCredentials
267
+ provider: str
268
+ redirect_uri: str
269
+ system_credentials: Mapping[str, Any]
270
+ credentials: Mapping[str, Any]
271
+
272
+
263
273
  class DynamicParameterFetchParameterOptionsRequest(BaseModel):
264
274
  type: PluginInvokeType = PluginInvokeType.DynamicParameter
265
275
  action: DynamicParameterActions = DynamicParameterActions.FetchParameterOptions
@@ -23,6 +23,7 @@ from dify_plugin.core.entities.plugin.request import (
23
23
  ModelValidateProviderCredentialsRequest,
24
24
  OAuthGetAuthorizationUrlRequest,
25
25
  OAuthGetCredentialsRequest,
26
+ OAuthRefreshCredentialsRequest,
26
27
  ToolGetRuntimeParametersRequest,
27
28
  ToolInvokeRequest,
28
29
  ToolValidateCredentialsRequest,
@@ -349,8 +350,23 @@ class PluginExecutor:
349
350
  bytes_data = binascii.unhexlify(data.raw_http_request)
350
351
  request = parse_raw_request(bytes_data)
351
352
 
353
+ credentials = provider_instance.oauth_get_credentials(data.redirect_uri, data.system_credentials, request)
354
+
355
+ return {
356
+ "metadata": credentials.metadata or {},
357
+ "credentials": credentials.credentials,
358
+ "expires_at": credentials.expires_at,
359
+ }
360
+
361
+ def refresh_oauth_credentials(self, session: Session, data: OAuthRefreshCredentialsRequest):
362
+ provider_instance = self._get_oauth_provider_instance(data.provider)
363
+ credentials = provider_instance.oauth_refresh_credentials(
364
+ data.redirect_uri, data.system_credentials, data.credentials
365
+ )
366
+
352
367
  return {
353
- "credentials": provider_instance.oauth_get_credentials(data.redirect_uri, data.system_credentials, request),
368
+ "credentials": credentials.credentials,
369
+ "expires_at": credentials.expires_at,
354
370
  }
355
371
 
356
372
  def _get_dynamic_parameter_action(
@@ -0,0 +1,35 @@
1
+ from collections.abc import Mapping, Sequence
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from dify_plugin.core.documentation.schema_doc import docs
7
+ from dify_plugin.entities.provider_config import ProviderConfig
8
+
9
+
10
+ @docs(
11
+ name="OAuthSchema",
12
+ description="The schema of the OAuth",
13
+ )
14
+ class OAuthSchema(BaseModel):
15
+ client_schema: Sequence[ProviderConfig] = Field(default_factory=list, description="The schema of the OAuth client")
16
+ credentials_schema: Sequence[ProviderConfig] = Field(
17
+ default_factory=list, description="The schema of the OAuth credentials"
18
+ )
19
+
20
+
21
+ class OAuthCredentials(BaseModel):
22
+ metadata: Mapping[str, Any] = Field(default_factory=dict, description="The metadata like avatar_url, name, etc.")
23
+ credentials: Mapping[str, Any] = Field(..., description="The credentials of the OAuth")
24
+ expires_at: int = Field(
25
+ default=-1, description="The timestamp of the credentials expiration, -1 means never expires"
26
+ )
27
+
28
+
29
+ class ToolOAuthCredentials(BaseModel):
30
+ credentials: Mapping[str, Any] = Field(..., description="The credentials of the tool")
31
+ expires_at: int | None = Field(
32
+ default=-1,
33
+ description="""The expiration timestamp (in seconds since Unix epoch, UTC) of the credentials.
34
+ Set to -1 or None if the credentials do not expire.""",
35
+ )
@@ -1,2 +1,6 @@
1
1
  class ToolProviderCredentialValidationError(Exception):
2
2
  pass
3
+
4
+
5
+ class ToolProviderOAuthError(Exception):
6
+ pass
@@ -147,6 +147,12 @@ class PluginRunner:
147
147
  os.close(self.stdin_pipe_read)
148
148
 
149
149
  def _read_async(self, fd: int) -> bytes:
150
+ import select
151
+
152
+ ready, _, _ = select.select([fd], [], [], 0.1)
153
+ if not ready:
154
+ return b""
155
+
150
156
  # read data from stdin using os.read in 64KB chunks.
151
157
  # the OS buffer for stdin is usually 64KB, so using a larger value doesn't make sense.
152
158
  b = os.read(fd, 65536)
@@ -155,6 +161,8 @@ class PluginRunner:
155
161
  return b
156
162
 
157
163
  def _message_reader(self, pipe: int):
164
+ import time
165
+
158
166
  # create a scanner to read the message line by line
159
167
  """Read messages line by line from the pipe."""
160
168
  buffer = b""
@@ -166,6 +174,7 @@ class PluginRunner:
166
174
  break
167
175
 
168
176
  if not data:
177
+ time.sleep(0.01)
169
178
  continue
170
179
 
171
180
  buffer += data
@@ -8,11 +8,13 @@ from werkzeug import Request
8
8
  from dify_plugin.core.runtime import Session
9
9
  from dify_plugin.entities import ParameterOption
10
10
  from dify_plugin.entities.invoke_message import InvokeMessage
11
+ from dify_plugin.entities.oauth import ToolOAuthCredentials
11
12
  from dify_plugin.entities.provider_config import LogMetadata
12
13
  from dify_plugin.entities.tool import ToolInvokeMessage, ToolParameter, ToolRuntime, ToolSelector
13
14
  from dify_plugin.file.constants import DIFY_FILE_IDENTITY, DIFY_TOOL_SELECTOR_IDENTITY
14
15
  from dify_plugin.file.entities import FileType
15
16
  from dify_plugin.file.file import File
17
+ from dify_plugin.protocol.oauth import OAuthCredentials
16
18
 
17
19
  T = TypeVar("T", bound=InvokeMessage)
18
20
 
@@ -234,24 +236,70 @@ class ToolProvider:
234
236
 
235
237
  def _validate_credentials(self, credentials: dict):
236
238
  raise NotImplementedError(
237
- "This plugin should implement `_validate_credentials` method to enable credentials validation"
239
+ "The tool you are using does not support credentials validation, "
240
+ "please implement `_validate_credentials` method"
238
241
  )
239
242
 
240
243
  def oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
244
+ """
245
+ Get the authorization url
246
+
247
+ :param redirect_uri: redirect uri
248
+ :param system_credentials: system credentials
249
+ :return: authorization url
250
+ """
241
251
  return self._oauth_get_authorization_url(redirect_uri, system_credentials)
242
252
 
243
253
  def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
244
- raise NotImplementedError("This method should be implemented by a subclass")
254
+ raise NotImplementedError(
255
+ "The tool you are using does not support OAuth, please implement `_oauth_get_authorization_url` method"
256
+ )
245
257
 
246
258
  def oauth_get_credentials(
247
259
  self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
248
- ) -> Mapping[str, Any]:
249
- return self._oauth_get_credentials(redirect_uri, system_credentials, request)
260
+ ) -> OAuthCredentials:
261
+ """
262
+ Get the credentials
263
+
264
+ :param redirect_uri: redirect uri
265
+ :param system_credentials: system credentials
266
+ :param request: raw http request
267
+ :return: credentials
268
+ """
269
+ tool_oauth_credentials = self._oauth_get_credentials(redirect_uri, system_credentials, request)
270
+ return OAuthCredentials(
271
+ credentials=tool_oauth_credentials.credentials, expires_at=tool_oauth_credentials.expires_at
272
+ )
250
273
 
251
274
  def _oauth_get_credentials(
252
275
  self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
253
- ) -> Mapping[str, Any]:
254
- raise NotImplementedError("This method should be implemented by a subclass")
276
+ ) -> ToolOAuthCredentials:
277
+ raise NotImplementedError(
278
+ "The tool you are using does not support OAuth, please implement `_oauth_get_credentials` method"
279
+ )
280
+
281
+ def oauth_refresh_credentials(
282
+ self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
283
+ ) -> OAuthCredentials:
284
+ """
285
+ Refresh the credentials
286
+
287
+ :param redirect_uri: redirect uri
288
+ :param system_credentials: system credentials
289
+ :param credentials: credentials
290
+ :return: refreshed credentials
291
+ """
292
+ tool_oauth_credentials = self._oauth_refresh_credentials(redirect_uri, system_credentials, credentials)
293
+ return OAuthCredentials(
294
+ credentials=tool_oauth_credentials.credentials, expires_at=tool_oauth_credentials.expires_at
295
+ )
296
+
297
+ def _oauth_refresh_credentials(
298
+ self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
299
+ ) -> ToolOAuthCredentials:
300
+ raise NotImplementedError(
301
+ "The tool you are using does not support OAuth, please implement `_oauth_refresh_credentials` method"
302
+ )
255
303
 
256
304
 
257
305
  class Tool(ToolLike[ToolInvokeMessage]):
@@ -322,6 +322,12 @@ class Plugin(IOServer, Router):
322
322
  and data.get("action") == OAuthActions.GetCredentials.value,
323
323
  )
324
324
 
325
+ self.register_route(
326
+ self.plugin_executer.refresh_oauth_credentials,
327
+ lambda data: data.get("type") == PluginInvokeType.OAuth.value
328
+ and data.get("action") == OAuthActions.RefreshCredentials.value,
329
+ )
330
+
325
331
  def _execute_request(
326
332
  self,
327
333
  session_id: str,
@@ -3,6 +3,8 @@ from typing import Any, Protocol
3
3
 
4
4
  from werkzeug import Request
5
5
 
6
+ from dify_plugin.entities.oauth import OAuthCredentials
7
+
6
8
 
7
9
  class OAuthProviderProtocol(Protocol):
8
10
  def oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
@@ -19,7 +21,7 @@ class OAuthProviderProtocol(Protocol):
19
21
  redirect_uri: str,
20
22
  system_credentials: Mapping[str, Any],
21
23
  request: Request,
22
- ) -> Mapping[str, Any]:
24
+ ) -> OAuthCredentials:
23
25
  """
24
26
  Get the credentials
25
27
  :param redirect_uri: redirect uri
@@ -28,3 +30,18 @@ class OAuthProviderProtocol(Protocol):
28
30
  :return: credentials
29
31
  """
30
32
  ...
33
+
34
+ def oauth_refresh_credentials(
35
+ self,
36
+ redirect_uri: str,
37
+ system_credentials: Mapping[str, Any],
38
+ credentials: Mapping[str, Any],
39
+ ) -> OAuthCredentials:
40
+ """
41
+ Refresh the credentials
42
+ :param redirect_uri: redirect uri
43
+ :param system_credentials: system credentials
44
+ :param credentials: credentials
45
+ :return: credentials
46
+ """
47
+ ...
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dify_plugin"
3
- version = "0.4.2b1"
3
+ version = "0.4.2b2"
4
4
  description = "Dify Plugin SDK"
5
5
  authors = [
6
6
  { name = "langgenius", email = "hello@dify.ai" },
@@ -1,17 +0,0 @@
1
- from collections.abc import Sequence
2
-
3
- from pydantic import BaseModel, Field
4
-
5
- from dify_plugin.core.documentation.schema_doc import docs
6
- from dify_plugin.entities.provider_config import ProviderConfig
7
-
8
-
9
- @docs(
10
- name="OAuthSchema",
11
- description="The schema of the OAuth",
12
- )
13
- class OAuthSchema(BaseModel):
14
- client_schema: Sequence[ProviderConfig] = Field(default_factory=list, description="The schema of the OAuth client")
15
- credentials_schema: Sequence[ProviderConfig] = Field(
16
- default_factory=list, description="The schema of the OAuth credentials"
17
- )
File without changes
File without changes