deepfos 1.1.31__tar.gz → 1.1.32__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 (181) hide show
  1. {deepfos-1.1.31 → deepfos-1.1.32}/PKG-INFO +1 -1
  2. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/_version.py +3 -3
  3. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/edb.py +51 -23
  4. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/deepmodel.py +92 -39
  5. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/eureka.py +26 -8
  6. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/sysutils.py +9 -2
  7. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/PKG-INFO +1 -1
  8. {deepfos-1.1.31 → deepfos-1.1.32}/MANIFEST.in +0 -0
  9. {deepfos-1.1.31 → deepfos-1.1.32}/README.md +0 -0
  10. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/__init__.py +0 -0
  11. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/algo/__init__.py +0 -0
  12. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/algo/graph.py +0 -0
  13. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/__init__.py +0 -0
  14. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/business_model.py +0 -0
  15. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/dimension.py +0 -0
  16. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/models/__init__.py +0 -0
  17. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/models/business_model.py +0 -0
  18. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_1/models/dimension.py +0 -0
  19. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_2/__init__.py +0 -0
  20. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_2/dimension.py +0 -0
  21. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_2/models/__init__.py +0 -0
  22. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/V1_2/models/dimension.py +0 -0
  23. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/__init__.py +0 -0
  24. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/account.py +0 -0
  25. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/accounting_engines.py +0 -0
  26. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/app.py +0 -0
  27. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/approval_process.py +0 -0
  28. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/base.py +0 -0
  29. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/business_model.py +0 -0
  30. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/consolidation.py +0 -0
  31. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/consolidation_process.py +0 -0
  32. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/datatable.py +0 -0
  33. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/deepconnector.py +0 -0
  34. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/deepfos_task.py +0 -0
  35. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/deepmodel.py +0 -0
  36. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/dimension.py +0 -0
  37. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/financial_model.py +0 -0
  38. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/journal_model.py +0 -0
  39. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/journal_template.py +0 -0
  40. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/memory_financial_model.py +0 -0
  41. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/__init__.py +0 -0
  42. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/account.py +0 -0
  43. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/accounting_engines.py +0 -0
  44. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/app.py +0 -0
  45. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/approval_process.py +0 -0
  46. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/base.py +0 -0
  47. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/business_model.py +0 -0
  48. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/consolidation.py +0 -0
  49. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/consolidation_process.py +0 -0
  50. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/datatable_mysql.py +0 -0
  51. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/deepconnector.py +0 -0
  52. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/deepfos_task.py +0 -0
  53. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/deepmodel.py +0 -0
  54. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/dimension.py +0 -0
  55. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/financial_model.py +0 -0
  56. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/journal_model.py +0 -0
  57. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/journal_template.py +0 -0
  58. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/memory_financial_model.py +0 -0
  59. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/platform.py +0 -0
  60. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/python.py +0 -0
  61. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/reconciliation_engine.py +0 -0
  62. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/reconciliation_report.py +0 -0
  63. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/role_strategy.py +0 -0
  64. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/smartlist.py +0 -0
  65. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/space.py +0 -0
  66. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/system.py +0 -0
  67. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/variable.py +0 -0
  68. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/models/workflow.py +0 -0
  69. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/platform.py +0 -0
  70. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/python.py +0 -0
  71. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/reconciliation_engine.py +0 -0
  72. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/reconciliation_report.py +0 -0
  73. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/role_strategy.py +0 -0
  74. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/smartlist.py +0 -0
  75. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/space.py +0 -0
  76. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/system.py +0 -0
  77. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/variable.py +0 -0
  78. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/api/workflow.py +0 -0
  79. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/__init__.py +0 -0
  80. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/jstream.c +0 -0
  81. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/jstream.pyx +0 -0
  82. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/pandas.c +0 -0
  83. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/pandas.pyx +0 -0
  84. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/py_jstream.py +0 -0
  85. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/boost/py_pandas.py +0 -0
  86. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/cache.py +0 -0
  87. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/config.py +0 -0
  88. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/__init__.py +0 -0
  89. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/__init__.py +0 -0
  90. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/_base.py +0 -0
  91. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/constants.py +0 -0
  92. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/cube.py +0 -0
  93. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/formula.py +0 -0
  94. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/syscube.py +0 -0
  95. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/typing.py +0 -0
  96. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/cube/utils.py +0 -0
  97. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/__init__.py +0 -0
  98. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/_base.py +0 -0
  99. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/dimcreator.py +0 -0
  100. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/dimension.py +0 -0
  101. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/dimexpr.py +0 -0
  102. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/dimmember.py +0 -0
  103. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/eledimension.py +0 -0
  104. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/filters.py +0 -0
  105. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/dimension/sysdimension.py +0 -0
  106. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/__init__.py +0 -0
  107. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/_cache.py +0 -0
  108. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/_operator.py +0 -0
  109. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/nodemixin.py +0 -0
  110. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/sqlcondition.py +0 -0
  111. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/core/logictable/tablemodel.py +0 -0
  112. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/__init__.py +0 -0
  113. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/cipher.py +0 -0
  114. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/clickhouse.py +0 -0
  115. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/connector.py +0 -0
  116. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/daclickhouse.py +0 -0
  117. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/dameng.py +0 -0
  118. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/damysql.py +0 -0
  119. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/dbkits.py +0 -0
  120. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/deepengine.py +0 -0
  121. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/deepmodel.py +0 -0
  122. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/deepmodel_kingbase.py +0 -0
  123. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/gauss.py +0 -0
  124. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/kingbase.py +0 -0
  125. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/mysql.py +0 -0
  126. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/oracle.py +0 -0
  127. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/postgresql.py +0 -0
  128. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/sqlserver.py +0 -0
  129. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/db/utils.py +0 -0
  130. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/__init__.py +0 -0
  131. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/accounting.py +0 -0
  132. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/apvlprocess.py +0 -0
  133. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/base.py +0 -0
  134. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/bizmodel.py +0 -0
  135. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/datatable.py +0 -0
  136. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/deepconnector.py +0 -0
  137. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/dimension.py +0 -0
  138. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/fact_table.py +0 -0
  139. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/finmodel.py +0 -0
  140. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/journal.py +0 -0
  141. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/journal_template.py +0 -0
  142. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/pyscript.py +0 -0
  143. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/reconciliation.py +0 -0
  144. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/rolestrategy.py +0 -0
  145. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/smartlist.py +0 -0
  146. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/variable.py +0 -0
  147. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/element/workflow.py +0 -0
  148. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/exceptions/__init__.py +0 -0
  149. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/exceptions/hook.py +0 -0
  150. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lazy.py +0 -0
  151. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/__init__.py +0 -0
  152. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/_javaobj.py +0 -0
  153. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/asynchronous.py +0 -0
  154. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/concurrency.py +0 -0
  155. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/constant.py +0 -0
  156. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/decorator.py +0 -0
  157. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/deepchart.py +0 -0
  158. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/deepux.py +0 -0
  159. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/discovery.py +0 -0
  160. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/filterparser.py +0 -0
  161. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/httpcli.py +0 -0
  162. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/jsonstreamer.py +0 -0
  163. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/nacos.py +0 -0
  164. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/patch.py +0 -0
  165. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/redis.py +0 -0
  166. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/serutils.py +0 -0
  167. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/stopwatch.py +0 -0
  168. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/subtask.py +0 -0
  169. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/lib/utils.py +0 -0
  170. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/local.py +0 -0
  171. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/options.py +0 -0
  172. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos/translation.py +0 -0
  173. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/SOURCES.txt +0 -0
  174. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/dependency_links.txt +0 -0
  175. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/not-zip-safe +0 -0
  176. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/requires.txt +0 -0
  177. {deepfos-1.1.31 → deepfos-1.1.32}/deepfos.egg-info/top_level.txt +0 -0
  178. {deepfos-1.1.31 → deepfos-1.1.32}/setup.cfg +0 -0
  179. {deepfos-1.1.31 → deepfos-1.1.32}/setup.py +0 -0
  180. {deepfos-1.1.31 → deepfos-1.1.32}/tests/__init__.py +0 -0
  181. {deepfos-1.1.31 → deepfos-1.1.32}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deepfos
3
- Version: 1.1.31
3
+ Version: 1.1.32
4
4
  Summary: Collecions of useful and handy tools for deepfos platform
5
5
  Home-page: http://py.deepfos.com
6
6
  Author: deepfos-python-team
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-03-26T03:15:02+0000",
11
+ "date": "2024-04-08T07:12:04+0000",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "52195bbba97196b1fd930df4bc7c5def16ab0a90",
15
- "version": "1.1.31"
14
+ "full-revisionid": "2eb652409a767c757a4324b2ceb60a88d649f355",
15
+ "version": "1.1.32"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,7 +1,14 @@
1
- from edgedb import AsyncIOClient, errors, enums, describe
2
- from edgedb.abstract import DescribeContext
3
- from edgedb.asyncio_client import AsyncIOConnection # noqa
4
- from edgedb.protocol import protocol
1
+ import asyncio
2
+
3
+ from edgedb import AsyncIOClient, errors, enums, describe, abstract
4
+ from edgedb.abstract import (
5
+ DescribeContext, QueryContext, QueryWithArgs,
6
+ _query_opts # noqa
7
+ )
8
+ from edgedb.asyncio_client import (
9
+ AsyncIOConnection, AsyncIOIteration, # noqa
10
+ AsyncIORetry
11
+ )
5
12
 
6
13
  from deepfos import OPTION
7
14
 
@@ -28,27 +35,11 @@ def collect_output_frame(ele_desc: describe.AnyType):
28
35
 
29
36
 
30
37
  class _AsyncEdgeDBConnection(AsyncIOConnection):
31
- async def _execute(self, execute_context) -> None:
32
- await self._protocol.execute(
33
- query=execute_context.query.query,
34
- args=execute_context.query.args,
35
- kwargs=execute_context.query.kwargs,
36
- reg=execute_context.cache.codecs_registry,
37
- qc=execute_context.cache.query_cache,
38
- output_format=protocol.OutputFormat.NONE,
39
- allow_capabilities=enums.Capability.MODIFICATIONS,
40
- state=(
41
- execute_context.state.as_dict()
42
- if execute_context.state else None
43
- ),
44
- )
45
-
46
- async def raw_query(self, query_context):
38
+ async def raw_query(self, query_context, capabilities=enums.Capability.NONE):
47
39
  if self.is_closed():
48
40
  await self.connect()
49
41
 
50
42
  reconnect = False
51
- capabilities = None
52
43
  i = 0
53
44
  args = dict(
54
45
  query=query_context.query.query,
@@ -59,7 +50,7 @@ class _AsyncEdgeDBConnection(AsyncIOConnection):
59
50
  output_format=query_context.query_options.output_format,
60
51
  expect_one=query_context.query_options.expect_one,
61
52
  required_one=query_context.query_options.required_one,
62
- allow_capabilities=enums.Capability.NONE,
53
+ allow_capabilities=capabilities,
63
54
  )
64
55
  if query_context.state is not None:
65
56
  args["state"] = query_context.state.as_dict()
@@ -123,6 +114,43 @@ class _AsyncEdgeDBConnection(AsyncIOConnection):
123
114
  reconnect = self.is_closed()
124
115
 
125
116
 
117
+ class _AsyncIOIteration(AsyncIOIteration):
118
+ async def _execute(self, query_context: abstract.QueryContext):
119
+ with self._exclusive():
120
+ await self._ensure_transaction()
121
+ return await self._connection.raw_query(
122
+ query_context, enums.Capability.MODIFICATIONS
123
+ )
124
+
125
+ async def execute(self, commands: str, *args, **kwargs):
126
+ return await self._execute(QueryContext(
127
+ query=QueryWithArgs(commands, args, kwargs),
128
+ cache=self._get_query_cache(),
129
+ query_options=_query_opts,
130
+ retry_options=self._get_retry_options(),
131
+ state=self._get_state(),
132
+ ))
133
+
134
+
135
+ class _AsyncIORetry(AsyncIORetry):
136
+ async def __anext__(self):
137
+ # Note: when changing this code consider also
138
+ # updating Retry.__next__.
139
+ if self._done:
140
+ raise StopAsyncIteration
141
+ if self._next_backoff:
142
+ await asyncio.sleep(self._next_backoff)
143
+ self._done = True
144
+ iteration = _AsyncIOIteration(self, self._owner, self._iteration)
145
+ self._iteration += 1
146
+ return iteration
147
+
148
+
149
+ class _AsyncIOClient(AsyncIOClient):
150
+ def transaction(self) -> _AsyncIORetry:
151
+ return _AsyncIORetry(self)
152
+
153
+
126
154
  # All deprecated space in v3dev & v3test & alpha
127
155
  deprecated_space = [
128
156
  'ulqtqb',
@@ -145,7 +173,7 @@ deprecated_space = [
145
173
  def create_async_client(default_module=None):
146
174
  space = OPTION.api.header['space']
147
175
  dbname = None if space in deprecated_space else f"deepmodel_space{space}"
148
- cli = AsyncIOClient(
176
+ cli = _AsyncIOClient(
149
177
  connection_class=_AsyncEdgeDBConnection,
150
178
  max_concurrency=None,
151
179
  dsn=OPTION.edgedb.dsn,
@@ -243,7 +243,7 @@ class BaseField(FieldInfo):
243
243
  # df[self.col_name] = df[self.col_name].astype(self.dtype, errors='ignore')
244
244
  pass
245
245
 
246
- def cast(self, df: pd.DataFrame, field_name: str):
246
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
247
247
  """
248
248
  对 :class:`Dataframe` 对应的列作类型转换。
249
249
  一般在获取 :class:`Dataframe` 时使用。
@@ -261,7 +261,7 @@ class FieldDateTime(BaseField):
261
261
  def extra_fit(self, df: pd.DataFrame, field_name: str):
262
262
  df[field_name] = df[field_name].apply(self.format_datetime)
263
263
 
264
- def cast(self, df: pd.DataFrame, field_name: str):
264
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
265
265
  df[field_name] = pd.to_datetime(df[field_name], errors='ignore')
266
266
 
267
267
 
@@ -281,11 +281,11 @@ class FieldJson(BaseField):
281
281
  return data
282
282
  return json.dumps(data)
283
283
 
284
- def cast(self, df: pd.DataFrame, field_name: str):
284
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
285
285
  # std::json needed to be cast only when data is from http
286
286
  # since json value will be converted to json string(type: str)
287
287
  # in edgedb python protocol
288
- if not ONLINE_MODE:
288
+ if not direct_access:
289
289
  df[field_name] = df[field_name].apply(self.format_json)
290
290
 
291
291
 
@@ -295,17 +295,17 @@ class FieldInt(FieldString):
295
295
  return pd.NA
296
296
  return str(int(data))
297
297
 
298
- def cast(self, df: pd.DataFrame, field_name: str):
298
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
299
299
  df[field_name] = df[field_name].astype(pd.Int64Dtype(), errors='ignore')
300
300
 
301
301
 
302
302
  class FieldDecimal(FieldString):
303
- def cast(self, df: pd.DataFrame, field_name: str):
303
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
304
304
  df[field_name] = df[field_name].astype(pd.Float64Dtype(), errors='ignore')
305
305
 
306
306
 
307
307
  class FieldBool(BaseField):
308
- def cast(self, df: pd.DataFrame, field_name: str):
308
+ def cast(self, df: pd.DataFrame, field_name: str, direct_access: bool = True):
309
309
  df[field_name] = df[field_name].astype(pd.BooleanDtype(), errors='ignore')
310
310
 
311
311
 
@@ -362,10 +362,10 @@ class ObjectStructure:
362
362
 
363
363
  return df[valid_fields]
364
364
 
365
- def cast(self, df: pd.DataFrame):
365
+ def cast(self, df: pd.DataFrame, direct_access: bool = True):
366
366
  for field in df.columns:
367
367
  if field in self.fields:
368
- self.fields[field].cast(df, field)
368
+ self.fields[field].cast(df, field, direct_access)
369
369
 
370
370
 
371
371
  def _iter_link_prop_assign(link, business_key, prop_name, prop_type, is_multi):
@@ -567,23 +567,25 @@ class _TxnConfig:
567
567
  self.txn_support = False
568
568
 
569
569
 
570
- if OPTION.edgedb.dsn:
571
- ONLINE_MODE = True
572
- else:
573
- ONLINE_MODE = False
574
-
575
-
576
570
  # -----------------------------------------------------------------------------
577
571
  # core
578
572
  class AsyncDeepModel(ElementBase[DeepModelAPI]):
579
573
  """DeepModel"""
580
574
 
581
- def __init__(self): # noqa
575
+ def __init__(self, direct_access: bool=True): # noqa
582
576
  self._txn_ = ContextVar('QLTXN')
583
577
  self.appmodule = f"app{OPTION.api.header['app']}"
584
578
  self.spacemodule = f"space{OPTION.api.header['space']}"
585
- if ONLINE_MODE:
579
+ self.direct_access = direct_access
580
+ if direct_access:
586
581
  self.client = create_async_client(default_module=self.appmodule)
582
+ if user_id := OPTION.api.header.get('user'):
583
+ self.client = self.client.with_globals(
584
+ **{
585
+ f'{self.spacemodule}::current_user_id':
586
+ user_id
587
+ }
588
+ )
587
589
  else:
588
590
  self.client = None
589
591
  self.alias = AliasGenerator()
@@ -690,7 +692,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
690
692
 
691
693
  """
692
694
 
693
- if ONLINE_MODE:
695
+ if self.direct_access:
694
696
  logger.opt(lazy=True).debug(f"Query: [{ql}], \nkwargs: [{kwargs}].")
695
697
  async with self.client as cli:
696
698
  _, result = await cli.query(ql, **kwargs)
@@ -726,7 +728,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
726
728
  :func:`query_object`, 执行ql查询语句,得到原始结果返回
727
729
 
728
730
  """
729
- if ONLINE_MODE:
731
+ if self.direct_access:
730
732
  logger.opt(lazy=True).debug(f"Query: [{ql}], \nkwargs: [{kwargs}].")
731
733
  async with self.client as cli:
732
734
  frame_desc, result = await cli.query(ql, **kwargs)
@@ -775,7 +777,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
775
777
  :func:`query_object`, 执行ql查询语句,得到原始结果返回
776
778
 
777
779
  """
778
- if ONLINE_MODE:
780
+ if self.direct_access:
779
781
  async with self.client as cli:
780
782
  frame_desc, data = await cli.query(ql, **kwargs)
781
783
 
@@ -803,7 +805,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
803
805
  if data.empty:
804
806
  return pd.DataFrame(columns=structure.fields.keys())
805
807
 
806
- structure.cast(data)
808
+ structure.cast(data, self.direct_access)
807
809
  return data
808
810
 
809
811
  query.__doc__ = query.__doc__ + DOC_ARGS_KWARGS
@@ -811,7 +813,11 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
811
813
  query_df.__doc__ = query_df.__doc__ + DOC_ARGS_KWARGS
812
814
 
813
815
  @txn_support
814
- async def execute(self, qls: Union[str, List[str], List[QueryWithArgs]], **kwargs):
816
+ async def execute(
817
+ self,
818
+ qls: Union[str, List[str], List[QueryWithArgs]],
819
+ **kwargs
820
+ ) -> Optional[List]:
815
821
  """以事务执行多句ql
816
822
 
817
823
  Args:
@@ -828,10 +834,12 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
828
834
  seen_kwargs_key = set()
829
835
  for ql in qls:
830
836
  if isinstance(ql, QueryWithArgs):
831
- if not ONLINE_MODE and ql.kwargs and seen_kwargs_key.intersection(
832
- ql.kwargs.keys()
837
+ if (
838
+ not self.direct_access
839
+ and ql.kwargs
840
+ and seen_kwargs_key.intersection(ql.kwargs.keys())
833
841
  ):
834
- raise NotImplementedError('线下模式不支持重名variables')
842
+ raise NotImplementedError('非直连模式不支持重名variables')
835
843
 
836
844
  qls_with_args.append(ql)
837
845
  if ql.kwargs:
@@ -842,19 +850,19 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
842
850
  else:
843
851
  raise TypeError(f'qls参数中出现类型非法成员:{type(ql)}')
844
852
 
845
- await self._maybe_exec_qls(qls_with_args)
853
+ return await self._maybe_exec_qls(qls_with_args)
846
854
 
847
855
  execute.__doc__ = execute.__doc__ + DOC_ARGS_KWARGS
848
856
 
849
- async def _execute(self, qls_with_args: List[QueryWithArgs]):
857
+ async def _execute(self, qls_with_args: List[QueryWithArgs]) -> List:
850
858
  self.alias.reset(BATCH_INSERT_KW)
851
- if not ONLINE_MODE:
859
+ if not self.direct_access:
852
860
  kwargs = {}
853
861
  seen_kwargs_key = set()
854
862
 
855
863
  for ql in qls_with_args:
856
864
  if ql.kwargs and seen_kwargs_key.intersection(ql.kwargs.keys()):
857
- raise NotImplementedError('线下模式不支持重名variables')
865
+ raise NotImplementedError('非直连模式不支持重名variables')
858
866
  if ql.kwargs:
859
867
  kwargs.update(ql.kwargs)
860
868
  seen_kwargs_key = seen_kwargs_key.union(ql.kwargs.keys())
@@ -869,9 +877,11 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
869
877
  query=commands,
870
878
  variables=self._prepare_variables(kwargs)
871
879
  )
872
- self._maybe_handle_error(res.get('json'))
873
- return
880
+ affected = res.get('json')
881
+ self._maybe_handle_error(affected)
882
+ return affected
874
883
 
884
+ result = []
875
885
  async with self.client as cli:
876
886
  async for tx in cli.transaction():
877
887
  async with tx:
@@ -879,7 +889,13 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
879
889
  logger.opt(lazy=True).debug(
880
890
  f"Execute QL: [{ql.commands}], \nkwargs: [{ql.kwargs}]."
881
891
  )
882
- await tx.execute(ql.commands, **ql.kwargs)
892
+ desc, affected = await tx.execute(ql.commands, **ql.kwargs)
893
+ result.append(serutils.serialize(
894
+ affected, ctx=serutils.Context(frame_desc=desc)
895
+ ))
896
+ if len(result) == 1:
897
+ return result[0]
898
+ return result
883
899
 
884
900
  @staticmethod
885
901
  def _maybe_handle_error(res):
@@ -891,14 +907,17 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
891
907
  ex_code = int(error['code'])
892
908
  raise edgedb.EdgeDBError._from_code(ex_code, ex_msg) # noqa
893
909
 
894
- async def _maybe_exec_qls(self, qls_with_args: List[QueryWithArgs]):
910
+ async def _maybe_exec_qls(
911
+ self,
912
+ qls_with_args: List[QueryWithArgs]
913
+ ) -> Optional[List]:
895
914
  txn_conf = self._safe_get_txn_conf()
896
915
 
897
916
  if txn_conf.in_txn and self._txn_support_:
898
917
  txn_conf.qls.extend(qls_with_args)
899
918
  return
900
919
 
901
- await self._execute(qls_with_args)
920
+ return await self._execute(qls_with_args)
902
921
 
903
922
  @txn_support
904
923
  async def insert_df(
@@ -909,7 +928,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
909
928
  chunksize: int = 500,
910
929
  enable_upsert: bool = False,
911
930
  update_fields: List[str] = None,
912
- ):
931
+ ) -> None:
913
932
  """以事务执行基于DataFrame字段信息的批量插入数据
914
933
 
915
934
  Args:
@@ -1119,7 +1138,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
1119
1138
  kwargs={kw_name: part.to_json(orient='records')}
1120
1139
  ))
1121
1140
 
1122
- def get_object(self, object_name):
1141
+ def get_object(self, object_name) -> edgedb.Object:
1123
1142
  if object_name in self.user_objects:
1124
1143
  obj = self.user_objects[object_name]
1125
1144
  elif object_name in self.system_objects:
@@ -1137,7 +1156,7 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
1137
1156
  obj: Union[ObjectTypeFrame, TargetField],
1138
1157
  source_name: str = None,
1139
1158
  field_name: str = None
1140
- ):
1159
+ ) -> str:
1141
1160
  # 如可在object结构的annotations中取业务主键,则优先取,否则走接口
1142
1161
  if obj.info and BUSINESS_KEY in obj.info:
1143
1162
  return obj.info[BUSINESS_KEY]
@@ -1262,6 +1281,36 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
1262
1281
  finally:
1263
1282
  self._txn_.set(_TxnConfig())
1264
1283
 
1284
+ @contextmanager
1285
+ def with_globals(self, globals_):
1286
+ if not self.direct_access:
1287
+ try:
1288
+ yield
1289
+ finally:
1290
+ raise NotImplemented('非直连模式不支持设置state信息')
1291
+ else:
1292
+ bak_cli = self.client
1293
+ try:
1294
+ self.client = self.client.with_globals(**globals_)
1295
+ yield
1296
+ finally:
1297
+ self.client = bak_cli
1298
+
1299
+ @contextmanager
1300
+ def without_globals(self, *global_names):
1301
+ if not self.direct_access:
1302
+ try:
1303
+ yield
1304
+ finally:
1305
+ raise NotImplemented('非直连模式不支持设置state信息')
1306
+ else:
1307
+ bak_cli = self.client
1308
+ try:
1309
+ self.client = self.client.without_globals(*global_names)
1310
+ yield
1311
+ finally:
1312
+ self.client = bak_cli
1313
+
1265
1314
 
1266
1315
  class DeepModel(AsyncDeepModel, metaclass=SyncMeta):
1267
1316
  synchronize = ('query_object', 'query', 'query_df', 'execute', 'insert_df')
@@ -1276,7 +1325,11 @@ class DeepModel(AsyncDeepModel, metaclass=SyncMeta):
1276
1325
  def query_df(self, ql: str, **kwargs) -> pd.DataFrame:
1277
1326
  ...
1278
1327
 
1279
- def execute(self, qls: Union[str, List[str], List[QueryWithArgs]], **kwargs):
1328
+ def execute(
1329
+ self,
1330
+ qls: Union[str, List[str], List[QueryWithArgs]],
1331
+ **kwargs
1332
+ ) -> Optional[List]:
1280
1333
  ...
1281
1334
 
1282
1335
  def insert_df(
@@ -1287,7 +1340,7 @@ class DeepModel(AsyncDeepModel, metaclass=SyncMeta):
1287
1340
  chunksize: int = 500,
1288
1341
  enable_upsert: bool = False,
1289
1342
  update_fields: List[str] = None,
1290
- ):
1343
+ ) -> None:
1291
1344
  ...
1292
1345
 
1293
1346
  @contextmanager
@@ -35,8 +35,13 @@ class EurekaCli(ServiceDiscovery):
35
35
 
36
36
  # noinspection PyAttributeOutsideInit
37
37
  def setup(self):
38
- self._app_url = concat_url(OPTION.server.eureka, 'apps')
39
- self._delta_url = concat_url(OPTION.server.eureka, 'apps/delta')
38
+ from deepfos.lib.discovery import CACHE_STRATEGY, RankedCache
39
+ base_url = CACHE_STRATEGY.get(
40
+ OPTION.discovery.cache_strategy, RankedCache
41
+ )()
42
+ for url in OPTION.server.eureka.split(','):
43
+ base_url.add(url)
44
+ self.base_url = base_url
40
45
 
41
46
  async def on_interval(self):
42
47
  if self.server_cache: # 有全量数据时-保持增量更新,否则-全量更新
@@ -63,11 +68,26 @@ class EurekaCli(ServiceDiscovery):
63
68
  async def update_instance_cache(self, server_name: str):
64
69
  pass
65
70
 
71
+ async def _get_xml(self, end_point: str):
72
+ if not self.base_url:
73
+ # Maybe all deleted by punish
74
+ self.setup()
75
+
76
+ url = self.base_url.pick_best()
77
+ try:
78
+ resp = await AioHttpCli.get(concat_url(url, end_point))
79
+ raw_xml = await resp.text()
80
+ xml = ElementTree.fromstring(raw_xml)
81
+ except Exception:
82
+ self.base_url.punish(url)
83
+ raise
84
+ else:
85
+ self.base_url.reward(url)
86
+ return xml
87
+
66
88
  async def _get_full_apps(self):
67
89
  """全量获取eureka服务列表,并更新到缓存中"""
68
- resp = await AioHttpCli.get(self._app_url)
69
- raw_xml = await resp.text()
70
- xml = ElementTree.fromstring(raw_xml)
90
+ xml = await self._get_xml('apps')
71
91
 
72
92
  # 全量更新:确保拿到数据后,先清缓存
73
93
  if xml.find('apps__hashcode').text:
@@ -91,9 +111,7 @@ class EurekaCli(ServiceDiscovery):
91
111
 
92
112
  async def get_delta_apps(self):
93
113
  """增量获取eureka服务列表,并更新到缓存中"""
94
- resp = await AioHttpCli.get(self._delta_url)
95
- raw_xml = await resp.text()
96
- xml = ElementTree.fromstring(raw_xml)
114
+ xml = await self._get_xml('apps/delta')
97
115
 
98
116
  server_memo = self.server_cache
99
117
  if (
@@ -225,10 +225,17 @@ def export_file_for_download(file_name: str, file: Union[str, bytes, TextIOWrapp
225
225
 
226
226
  # . 提供buffer
227
227
  import io
228
+ import pandas as pd
228
229
 
229
230
  buffer = io.BytesIO()
230
- buffer.write(b'8888')
231
- export_file_for_download('t4.txt', buffer.getbuffer())
231
+ # 将dataframe内容写入buffer
232
+ with pd.ExcelWriter(buffer, engine="openpyxl") as writer:
233
+ pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]}).to_excel(
234
+ writer, index=False, encoding='utf-8'
235
+ )
236
+
237
+ # 上传至下载中心
238
+ export_file_for_download('out.xlsx', buffer.getbuffer())
232
239
 
233
240
 
234
241
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deepfos
3
- Version: 1.1.31
3
+ Version: 1.1.32
4
4
  Summary: Collecions of useful and handy tools for deepfos platform
5
5
  Home-page: http://py.deepfos.com
6
6
  Author: deepfos-python-team
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes