gibson-cli 0.1.0__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.
Files changed (102) hide show
  1. api/BaseApi.py +45 -0
  2. api/Cli.py +248 -0
  3. bin/gibson.py +16 -0
  4. command/Api.py +31 -0
  5. command/Base.py +28 -0
  6. command/BaseCommand.py +26 -0
  7. command/Build.py +69 -0
  8. command/Code.py +198 -0
  9. command/Conf.py +74 -0
  10. command/Count.py +35 -0
  11. command/Dev.py +121 -0
  12. command/Forget.py +34 -0
  13. command/Import.py +109 -0
  14. command/List.py +61 -0
  15. command/Merge.py +35 -0
  16. command/Model.py +42 -0
  17. command/Models.py +31 -0
  18. command/Modify.py +43 -0
  19. command/Module.py +42 -0
  20. command/New.py +38 -0
  21. command/OpenApi.py +141 -0
  22. command/Question.py +105 -0
  23. command/Remove.py +80 -0
  24. command/Rename.py +71 -0
  25. command/Rewrite.py +107 -0
  26. command/Schema.py +42 -0
  27. command/Schemas.py +31 -0
  28. command/Show.py +37 -0
  29. command/Test.py +42 -0
  30. command/Tests.py +31 -0
  31. command/Tree.py +92 -0
  32. command/WarGames.py +35 -0
  33. command/auth/Auth.py +25 -0
  34. command/auth/Login.py +17 -0
  35. command/auth/Logout.py +7 -0
  36. command/tests/test_command_BaseCommand.py +10 -0
  37. command/tests/test_command_Conf.py +19 -0
  38. conf/Api.py +3 -0
  39. conf/Code.py +9 -0
  40. conf/Custom.py +4 -0
  41. conf/Datastore.py +4 -0
  42. conf/Dependencies.py +24 -0
  43. conf/Dev.py +15 -0
  44. conf/Frameworks.py +7 -0
  45. conf/Modeler.py +3 -0
  46. conf/Paths.py +10 -0
  47. conf/Platform.py +16 -0
  48. conf/Project.py +18 -0
  49. conf/Version.py +2 -0
  50. conf/dev/Api.py +5 -0
  51. conf/dev/Base.py +3 -0
  52. conf/dev/Model.py +3 -0
  53. conf/dev/Schema.py +3 -0
  54. conf/tests/test_conf_Dependencies.py +5 -0
  55. conf/tests/test_conf_Platform.py +7 -0
  56. core/CommandRouter.py +249 -0
  57. core/Configuration.py +418 -0
  58. core/Conversation.py +270 -0
  59. core/Env.py +12 -0
  60. core/Memory.py +148 -0
  61. core/TimeKeeper.py +12 -0
  62. core/utils.py +19 -0
  63. data/default-ref-table.tmpl +4 -0
  64. data/default-table.tmpl +6 -0
  65. db/TableExceptions.py +6 -0
  66. db/tests/test_db_TableExceptions.py +9 -0
  67. dev/Dev.py +92 -0
  68. display/Header.py +6 -0
  69. display/WorkspaceFooter.py +10 -0
  70. display/WorkspaceHeader.py +8 -0
  71. display/tests/test_display_Header.py +9 -0
  72. display/tests/test_display_WorkspaceFooter.py +9 -0
  73. display/tests/test_display_WorkspaceHeader.py +8 -0
  74. gibson_cli-0.1.0.dist-info/METADATA +306 -0
  75. gibson_cli-0.1.0.dist-info/RECORD +102 -0
  76. gibson_cli-0.1.0.dist-info/WHEEL +5 -0
  77. gibson_cli-0.1.0.dist-info/entry_points.txt +2 -0
  78. gibson_cli-0.1.0.dist-info/top_level.txt +12 -0
  79. lang/Python.py +57 -0
  80. lang/tests/test_lang_Python.py +70 -0
  81. services/auth/Server.py +75 -0
  82. services/code/context/schema/DataDictionary.py +12 -0
  83. services/code/context/schema/EntityKeys.py +49 -0
  84. services/code/context/schema/Manager.py +28 -0
  85. services/code/context/schema/tests/test_code_context_schema_DataDictionary.py +8 -0
  86. services/code/context/schema/tests/test_code_context_schema_EntityKeys.py +52 -0
  87. services/code/context/schema/tests/test_code_context_schema_Manager.py +34 -0
  88. services/code/customization/Authenticator.py +51 -0
  89. services/code/customization/BaseCustomization.py +12 -0
  90. services/code/customization/CustomizationManager.py +20 -0
  91. services/code/customization/tests/test_code_customization_Authenticator.py +53 -0
  92. services/code/customization/tests/test_code_customization_BaseCustomization.py +14 -0
  93. structure/Entity.py +115 -0
  94. structure/constraints/ReferenceConstraint.py +36 -0
  95. structure/keys/ForeignKey.py +41 -0
  96. structure/keys/Index.py +64 -0
  97. structure/keys/IndexAttribute.py +14 -0
  98. structure/keys/tests/test_ForeignKey.py +80 -0
  99. structure/keys/tests/test_Index.py +98 -0
  100. structure/keys/tests/test_IndexAttribute.py +17 -0
  101. structure/testing.py +194 -0
  102. structure/tests/test_Entity.py +107 -0
@@ -0,0 +1,102 @@
1
+ api/BaseApi.py,sha256=W5C_Rq-sf_MOwArozYG0ILFL8nyXhSwX84dpLT69o1M,1055
2
+ api/Cli.py,sha256=CPl_VnNuPyXkQNIv-YNfKpQbAdJIP8i2DeHbsmodXlA,8380
3
+ bin/gibson.py,sha256=Ip7qGG6yR_lCQYkBTgfpMXS-OT2meB6kYnK9gL53hvI,340
4
+ command/Api.py,sha256=-dGNE5StHlmN97g59mFraUZcaBEk5sBBMLShJoG4Yb8,961
5
+ command/Base.py,sha256=OqN_O8wAq_swESCBQ1bF5j4AT1K4PAjep68u-WxGT7U,785
6
+ command/BaseCommand.py,sha256=y0qD75qQ7b_phn3z2JSsraDpKovF_CEqiSUld_0LwrY,763
7
+ command/Build.py,sha256=8Gw1dSakBsgNiAw5rKLTuhf6qAXGONQ--_XCx5j2k9s,2551
8
+ command/Code.py,sha256=ltmU5htLvFShh-jgf0hdfKaENvkIE2vl_IGuGU_Z6K8,6725
9
+ command/Conf.py,sha256=afZMpJ-tS1wcY3s6cjNjmW6d8hihRw-mZvaS7hFV47w,2376
10
+ command/Count.py,sha256=xsYPRXP8TrW0T8P6uhjuovc28oR2iQgukL81eLoMpOc,976
11
+ command/Dev.py,sha256=gD_0AeQ0uPNCMsYAAIrCJBefKicMaLYHmFf2kog7H-Y,4218
12
+ command/Forget.py,sha256=iM8SdUMMdiw8Vbn3bJ6dgdnNXg-MIt3VM4G1ix3Kei4,1058
13
+ command/Import.py,sha256=4jNHpKSn_vjCUC1GUY1ZiLiMpSJuWyxLYJBi2W_jfeQ,3649
14
+ command/List.py,sha256=L2eTIxivZqalXQ4TwdSukGXVJ60bnPN0DA0MKdBfC84,2154
15
+ command/Merge.py,sha256=afiEZaY7BPwV91S0T0KbZJ7JHh-BhoAvmQhbzyGZZJo,1069
16
+ command/Model.py,sha256=P6Eo61zOj--C565m7nYe6lUnJJWr0utw7Eavlpt35VA,1195
17
+ command/Models.py,sha256=wzJqqdvPr-7vn4F_zqKPr7f70qHe1k7nGtteEjRPoz0,897
18
+ command/Modify.py,sha256=gRqbBdrUeRt1xhdAPNyiqgStTC3zrsm0EWng4FbwWgM,1256
19
+ command/Module.py,sha256=LKBCYagACPLqSC4emRXszX_f3lvhlmD9Kgh0kzCto8I,1260
20
+ command/New.py,sha256=ojmlN1YEs71uwouLDuSO_Eox4PDcTAZ8Sw32xWlrjWA,1137
21
+ command/OpenApi.py,sha256=G8R_Dc8hPLCgWZAMNHIgHN9JBfnfDrDdT2ie0a-Rrx4,4321
22
+ command/Question.py,sha256=vH04VrSXak4rOnYvV2e1eTGScli-_vIPyA9NR8PlmIA,3728
23
+ command/Remove.py,sha256=vkBeD641MvbR9YwwXpq2Cej36QWwt-VTzn8XBDpxmpE,2356
24
+ command/Rename.py,sha256=XOYAHkckYw5m4Vr_XomjkyhZT2QGlmv7yZnFUW38-3w,2186
25
+ command/Rewrite.py,sha256=yh7IPjtN7y0YzXs9K-I5E47SRVziI7bp0gis_8S_PGM,3111
26
+ command/Schema.py,sha256=U6SH_fTfEprIvvX8eDmHoMC4B6AfaGMrR17co13JO2M,1199
27
+ command/Schemas.py,sha256=d4zgLFrXaaBSuAX8ouy429DXiWnx6uwEeFUDWAr4NmA,900
28
+ command/Show.py,sha256=oNGKeNfEo6Qz1n4rJIRjlLuHWHWs5lB0TWE8Vn3hE2U,1190
29
+ command/Test.py,sha256=2zfxSTm-lwvzERTZNgD99z-AtOWb4RdAN1B93aa-UEk,1194
30
+ command/Tests.py,sha256=1l8iJs2W6fJDKMPL9Qdx7Qzm2I3azg_esthrZihK-S4,897
31
+ command/Tree.py,sha256=JWvUimeHWY5-6vEh6axTkhAdI-dVTxbKSjx_4isAAx8,3041
32
+ command/WarGames.py,sha256=vgMXSddUEU_PwDKyI7K0j-FN7uPs5jznfRj-CWh78FI,1280
33
+ command/auth/Auth.py,sha256=taUwmwAsJWN19oKmjgVGhPA_A8vj6vQLmNUVkuiqfjg,666
34
+ command/auth/Login.py,sha256=C3ZzV-Pp1C4RtAhpJ3IkJIwfgRY8pcUQmZRyMLT5hpU,454
35
+ command/auth/Logout.py,sha256=kxyHEGUXp4Ql6VS9R0eQfZqRDf8yhAslZNXExwh1gjY,199
36
+ command/tests/test_command_BaseCommand.py,sha256=BCeceiGl6ljjxkPiHMKzzrzjK1BUPWTHu9fTwGIETJI,350
37
+ command/tests/test_command_Conf.py,sha256=4tgWLoIYNuv-bmCAFFy2Kl9nau5KtCwKJMKwMCfL8ow,569
38
+ conf/Api.py,sha256=GM9okYs1A8ujPjDwzziOoQpqRYFkr-dz5pgkfb6j4DI,59
39
+ conf/Code.py,sha256=3Bd5kxCbgWaUOyYLRejOO_SqM9spGk1dYAf2hYzuDSw,199
40
+ conf/Custom.py,sha256=7S5v3bQK3UKuGUMTrAJeubWqszDtMlJI19-yOXk1TFs,101
41
+ conf/Datastore.py,sha256=PVAnysrk4wH1oCWxTUaakH2_x83Zpm4vzD1ELhfMDSw,90
42
+ conf/Dependencies.py,sha256=DZxyFtDR_3QpmsZbHApJFSeA7uYrMX1Bdx4lZKJ49Uo,891
43
+ conf/Dev.py,sha256=xWccZPN5lW2j9O5ZfBDS9gMmxf75AhjGaDUnw0abEyo,316
44
+ conf/Frameworks.py,sha256=Dv5iqeVe0JmNCKX5a-6S_dCrx7WZyI3qkTAFX6JWfDU,173
45
+ conf/Modeler.py,sha256=RayW3VFD_2nCFXZepfEcCXTUX2tWd7WtOjHULNVCai8,67
46
+ conf/Paths.py,sha256=NHJ_YLzmTIUUVLvtZornRdl1xPSluSmpFlMNsnqonxA,192
47
+ conf/Platform.py,sha256=ai7bLab2Ak_zWiANJH78Pj3YjTlTCQ1EEtkFaVDijOc,307
48
+ conf/Project.py,sha256=2lc_rr7giu1aGA4Ue4sU3Ey8-_yB2orLM1cw8f9zcdo,440
49
+ conf/Version.py,sha256=S_mJGw2v6jONwOHFgzEGwVDr-Ng4M4a3Z6CPrF38TzM,33
50
+ conf/dev/Api.py,sha256=EKZwy-3h7NxLdP6AYtwyTpJhD1kdQN6gVLuWw4_2KC8,158
51
+ conf/dev/Base.py,sha256=HisA87syPa5sJFjfjyxWRkLIKuVM5CtAkwW3f2zJx5Y,72
52
+ conf/dev/Model.py,sha256=HbHRX3VDxR7hXlzuxkKw4Bf7FH6XMfQ96k9BeIUoBf4,73
53
+ conf/dev/Schema.py,sha256=kOSlX1jEyVb82xd8TO8jEAimLcaefIFJr6d2JYvyTqg,74
54
+ conf/tests/test_conf_Dependencies.py,sha256=zmUFIANwpmFSMeEV5CllJstaqSSOBh9-Vgk-nETdlx0,109
55
+ conf/tests/test_conf_Platform.py,sha256=amq1YqxHOXimIP6eIoSg-hAKZ8S68cDAXRdNEaTkdfw,131
56
+ core/CommandRouter.py,sha256=fIzXKcGciMDHuXLkb6tp_N6sKs5SoqduCt-F1FE2U_c,9169
57
+ core/Configuration.py,sha256=Rw8g0W11BK1TW7WdWef6tIB4YVLuRGiUtn-VjL8OFu0,13881
58
+ core/Conversation.py,sha256=l9-8laUpHMtg14o4hzEho_CAX4Ahh2niVKUF3-0milI,8106
59
+ core/Env.py,sha256=ulL7y1xqlz6Mrg_hVUM3NzSumDCI2B1Zjfz9StT2Ju0,413
60
+ core/Memory.py,sha256=A7YtZFZwHqYpTFODsms8r_RNFNj3l-HKmaD8DhKH6So,3910
61
+ core/TimeKeeper.py,sha256=0mzs04wizjGEJbiQFWZyi4ja4XgeJaDqc0JzPCHp9po,250
62
+ core/utils.py,sha256=KTnPvA3sUYnLFTZG7Tke5YEdls8Da0rNbeaOm8hapiU,408
63
+ data/default-ref-table.tmpl,sha256=cVqjTsmHDjmTGrbDEpNHaDG-GX1iWMzsQDXk5TASEXg,123
64
+ data/default-table.tmpl,sha256=4t7SmXBuZN4nV5SjuQp6PBdo0-c3hdRnl8TQ2wdaS3w,247
65
+ db/TableExceptions.py,sha256=F1NGHDhusg9E_3tLez1_abrbANtWyR0UtC_wE9CwNFE,137
66
+ db/tests/test_db_TableExceptions.py,sha256=siPrXUBenRHW5nOO-n1eExTwgaJgZASAYdhDJXeXTJg,215
67
+ dev/Dev.py,sha256=QWdzf1mvi95WCEMHnlnk8Xj5k75mBQE3-hTH3yiFESE,2888
68
+ display/Header.py,sha256=moTxePVMNhtpeFtcI9EhnnLSK1gHIQiwYiWQtBPq_bY,298
69
+ display/WorkspaceFooter.py,sha256=1-PsPtLcC7xUZLwufSSaVo9caXuyZEwfR_iZatxwHF4,316
70
+ display/WorkspaceHeader.py,sha256=1oyyhZJF6C0SUCY2Cs_VkXt5Plp8xLb51XWa278l9mo,217
71
+ display/tests/test_display_Header.py,sha256=rQ7ip3ViJ62H9sFFWGjsLEn8c4C2s4KJpFhaeah4crY,317
72
+ display/tests/test_display_WorkspaceFooter.py,sha256=fDxXdwDmQLIRWYIBHbh32gfy2eW6Nlc4uq3wCOtGLIM,352
73
+ display/tests/test_display_WorkspaceHeader.py,sha256=Mhloli8KkyVFqv3-Ci4CDggXjrdJ5xebyZmw4foxsuE,309
74
+ lang/Python.py,sha256=qplU7xoplAIwWTTUSP1RcG3eMhHNUcbyJxCh1yZsXP8,1672
75
+ lang/tests/test_lang_Python.py,sha256=nulN-VSftAG2BM9HGFUP2RGUHebJAOCWIVPLbHY96Uk,1961
76
+ services/auth/Server.py,sha256=s5qNHxhY-ySSGa2RaK4zZIS3K908ulihx35d2F2Xg2k,1973
77
+ services/code/context/schema/DataDictionary.py,sha256=zWLzxOzW8iMHxfXPEwnnbruEAtFa8j1UpghNd4AHzfA,369
78
+ services/code/context/schema/EntityKeys.py,sha256=c8psaGfKseGN9V84xTjotgoLNs41sshbgX9K6ToFXHI,1548
79
+ services/code/context/schema/Manager.py,sha256=rzj4eTfLn2NDJVop4VWqedNZ6oN0ST1hXqK54UwHe5A,892
80
+ services/code/context/schema/tests/test_code_context_schema_DataDictionary.py,sha256=ASqifx7re5BU2RDKV3S0T00jxQTEiGEXa7rRcOeqa8E,357
81
+ services/code/context/schema/tests/test_code_context_schema_EntityKeys.py,sha256=vdynazkI_TMGo5TVvhDeAelU08FrXOKMHx-jF05jOs0,2086
82
+ services/code/context/schema/tests/test_code_context_schema_Manager.py,sha256=xVGeYj838VwhLNVIWYBDijBO7ObIPfSfVrU0DUlLweo,1216
83
+ services/code/customization/Authenticator.py,sha256=5qnBjO_U7GhuQkC0boGgjqo5YTe-axyBWkl2ggkLg2I,1565
84
+ services/code/customization/BaseCustomization.py,sha256=YZT3yP6cObTTPWjIvOyt5Cf6sRNVHtEXDJEmtcRRrzc,286
85
+ services/code/customization/CustomizationManager.py,sha256=U4TFhIGUyUtJfeP72Ke9fxVTR3sonRDU2lFFLprCq68,570
86
+ services/code/customization/tests/test_code_customization_Authenticator.py,sha256=eKOZ1F6zpSQsLo8bpjvcYozlGGGv8Gll7MSMXBWyUTs,1935
87
+ services/code/customization/tests/test_code_customization_BaseCustomization.py,sha256=RUTepr2upveeEZowszk8HEEVBQ7y2MQin_Sh5BhKEAI,398
88
+ structure/Entity.py,sha256=iDEtPy0fEAniABxffLxiYF6wWHQdrIWgW4L_-gB4hOA,3518
89
+ structure/testing.py,sha256=NAXg4JWb_ysS-OCWZyJ4413vv7FnnWCyjD9Tj4dK_VM,7545
90
+ structure/constraints/ReferenceConstraint.py,sha256=5zzKk--A2Bu1ZsN8QqS4jNILwq_BhOrV-f26WHKz5I0,1145
91
+ structure/keys/ForeignKey.py,sha256=1XN_XssLz6NcQp3vf91TrBZ7006xZKnPnTexu-nvpKQ,1230
92
+ structure/keys/Index.py,sha256=k5QfUyQM6hRkCNq1NtWWuAGxElmG4bXSCSRivzjr9g4,1694
93
+ structure/keys/IndexAttribute.py,sha256=GL-ma2v_GidZ6jjIlFc6IWKe4Gtg4UJUlqf1cYisqS0,298
94
+ structure/keys/tests/test_ForeignKey.py,sha256=rcNEgHpYjg5fYsbSHa1zd_N09NFRRyimDhVSnd13RQs,2261
95
+ structure/keys/tests/test_Index.py,sha256=0ZFHEnU5DJBtxG2TCavVD13Rq6aloUXPFM1bspWhbXg,2163
96
+ structure/keys/tests/test_IndexAttribute.py,sha256=_v3aKmL06cgXuV3xLXJMdp-8oPxHStj7qymtF3HtGrQ,381
97
+ structure/tests/test_Entity.py,sha256=MYog9b_IV3gbfYx9_hPmCgX3JNPz0t6cXQ-LU1WobjE,3117
98
+ gibson_cli-0.1.0.dist-info/METADATA,sha256=OMPI6DftiUJ_LO30DLGRDp9-d9nwswwLVQb9Lr77x2I,10886
99
+ gibson_cli-0.1.0.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
100
+ gibson_cli-0.1.0.dist-info/entry_points.txt,sha256=VAGCYo_zQgGI5bYR4Ql4rHhl5Zt7iA-Irt1v4iriLvQ,43
101
+ gibson_cli-0.1.0.dist-info/top_level.txt,sha256=e26JAjLAeXm2tl9nuW9OxrRvzkIXNYlXnHo-Yf5ZtnE,70
102
+ gibson_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (71.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gibson = bin.gibson:main
@@ -0,0 +1,12 @@
1
+ api
2
+ bin
3
+ command
4
+ conf
5
+ core
6
+ data
7
+ db
8
+ dev
9
+ display
10
+ lang
11
+ services
12
+ structure
lang/Python.py ADDED
@@ -0,0 +1,57 @@
1
+ import os
2
+
3
+
4
+ class Python:
5
+ def define_python_path(self, paths: list):
6
+ additions = []
7
+ for entry in paths:
8
+ path = self.make_python_path(entry)
9
+ if path is not None:
10
+ add_path = True
11
+ for addition in additions:
12
+ if addition in path:
13
+ add_path = False
14
+ break
15
+
16
+ if add_path:
17
+ additions.append(path)
18
+
19
+ if additions == []:
20
+ return None
21
+
22
+ return ":".join(additions)
23
+
24
+ def make_import_path(self, os_path):
25
+ if os_path is None:
26
+ return None
27
+
28
+ os_path = os.path.expandvars(os_path)
29
+
30
+ pythonpath = os.environ["PYTHONPATH"].split(":")
31
+ for entry in pythonpath:
32
+ path = os_path.replace(entry, "")
33
+ if path != os_path:
34
+ path = path.replace("/", ".")
35
+ if path in [None, ""]:
36
+ # There is no import path, the file is at the top level. Note,
37
+ # this is explicitly not None as that will cause the back end
38
+ # to incorrectly exclude the import.
39
+ return ""
40
+
41
+ if path[0] == ".":
42
+ path = path[1:]
43
+
44
+ return path
45
+
46
+ raise RuntimeError(
47
+ "cannot make import path; please execute:\n\n"
48
+ + f" export PYTHONPATH=$PYTHONPATH:{os_path}\n"
49
+ )
50
+
51
+ def make_python_path(self, path):
52
+ pythonpath = os.environ["PYTHONPATH"].split(":")
53
+ for entry in pythonpath:
54
+ if entry in path:
55
+ return None
56
+
57
+ return path
@@ -0,0 +1,70 @@
1
+ import os
2
+
3
+ import pytest
4
+
5
+ from lang.Python import Python
6
+
7
+
8
+ def test_make_python_path_no_match():
9
+ assert Python().make_python_path("/a/b/c") == "/a/b/c"
10
+
11
+
12
+ def test_make_python_path_match():
13
+ last_pythonpath = os.environ["PYTHONPATH"]
14
+
15
+ try:
16
+ os.environ["PYTHONPATH"] = "/a/b/c:/d/e/f"
17
+ assert Python().make_python_path("/a/b/c/g") is None
18
+ assert Python().make_python_path("/d/e/f/h") is None
19
+ finally:
20
+ os.environ["PYTHONPATH"] = last_pythonpath
21
+
22
+
23
+ def test_define_python_path():
24
+ last_pythonpath = os.environ["PYTHONPATH"]
25
+
26
+ try:
27
+ os.environ["PYTHONPATH"] = "/a/b/c:/d/e/f"
28
+ assert Python().define_python_path(["/a/b/c", "/d/e/f"]) is None
29
+ assert Python().define_python_path(["/g/h/i", "/j/k/l"]) == "/g/h/i:/j/k/l"
30
+ finally:
31
+ os.environ["PYTHONPATH"] = last_pythonpath
32
+
33
+
34
+ def test_make_import_path_exceptions():
35
+ with pytest.raises(RuntimeError) as e:
36
+ Python().make_import_path("/a/b/c")
37
+
38
+ assert str(e.value) == (
39
+ """cannot make import path; please execute:
40
+
41
+ export PYTHONPATH=$PYTHONPATH:/a/b/c
42
+ """
43
+ )
44
+
45
+
46
+ def test_make_import_path():
47
+ last_pythonpath = os.environ["PYTHONPATH"]
48
+
49
+ try:
50
+ os.environ["PYTHONPATH"] = "/a/b/c"
51
+ assert Python().make_import_path(None) is None
52
+ assert Python().make_import_path("/a/b/c/services/base") == "services.base"
53
+ assert Python().make_import_path("/a/b/c/services/base/model") == (
54
+ "services.base.model"
55
+ )
56
+ assert Python().make_import_path("/a/b/c/services/base/schema") == (
57
+ "services.base.schema"
58
+ )
59
+ finally:
60
+ os.environ["PYTHONPATH"] = last_pythonpath
61
+
62
+
63
+ def test_make_import_path_match_on_top_level():
64
+ last_pythonpath = os.environ["PYTHONPATH"]
65
+
66
+ try:
67
+ os.environ["PYTHONPATH"] = "/a/b/c"
68
+ assert Python().make_import_path("/a/b/c") == ""
69
+ finally:
70
+ os.environ["PYTHONPATH"] = last_pythonpath
@@ -0,0 +1,75 @@
1
+ import webbrowser
2
+
3
+ import time
4
+ from http.server import HTTPServer, BaseHTTPRequestHandler
5
+ from threading import Thread
6
+ from socket import socket
7
+ from urllib.parse import urlparse, parse_qs
8
+
9
+
10
+ # HTTP handler for processing the token sent from the web browser
11
+ class Handler(BaseHTTPRequestHandler):
12
+ def do_GET(self):
13
+ url = urlparse(self.path)
14
+ params = parse_qs(url.query)
15
+ token = params.get("token", [""])[0]
16
+
17
+ if token:
18
+ self.respond(200, "OK")
19
+ self.server.token = token
20
+ else:
21
+ self.respond(400, "Bad Request")
22
+
23
+ self.server._stop()
24
+
25
+ # Suppress logging
26
+ def log_message(self, format, *args):
27
+ pass
28
+
29
+ # Format the response
30
+ def respond(self, code, message):
31
+ self.send_response(code)
32
+ self.send_header("Content-type", "text")
33
+ self.send_header("Access-Control-Allow-Origin", "*")
34
+ self.send_header(
35
+ "Access-Control-Allow-Headers",
36
+ "Origin, X-Requested-With, Content-Type, Accept",
37
+ )
38
+ self.end_headers()
39
+ self.wfile.write(message.encode("utf8"))
40
+
41
+
42
+ # Temporary HTTP server to handle the login process
43
+ class Server(HTTPServer):
44
+ port = None
45
+ token = None
46
+ thread = None
47
+
48
+ def __init__(self, app_domain: str):
49
+ sock = socket()
50
+ sock.bind(("", 0))
51
+ self.port = sock.getsockname()[1]
52
+ super().__init__(("localhost", self.port), Handler)
53
+
54
+ self.app_domain = app_domain
55
+
56
+ def get_token(self):
57
+ self._start()
58
+ self._open_browser()
59
+
60
+ while self.thread is not None:
61
+ time.sleep(1)
62
+
63
+ return self.token
64
+
65
+ def _open_browser(self):
66
+ webbrowser.open(f"{self.app_domain}/signup?cli={self.port}")
67
+
68
+ def _start(self):
69
+ thread = Thread(target=self.serve_forever)
70
+ thread.start()
71
+ self.thread = thread
72
+
73
+ def _stop(self):
74
+ Thread(target=self.shutdown).start()
75
+ self.thread = None
@@ -0,0 +1,12 @@
1
+ class DataDictionary:
2
+ def __init__(self):
3
+ self.__attributes = {}
4
+
5
+ def from_code_writer_schema_context(self, data: dict):
6
+ for name, definition in data.items():
7
+ self.__attributes[name] = definition
8
+
9
+ return self
10
+
11
+ def get_attribute_definition(self, attribute_name):
12
+ return self.__attributes.get(attribute_name, None)
@@ -0,0 +1,49 @@
1
+ from structure.constraints.ReferenceConstraint import ReferenceConstraint
2
+ from structure.keys.ForeignKey import ForeignKey
3
+ from structure.keys.Index import Index
4
+
5
+
6
+ class EntityKeys:
7
+ def __init__(self):
8
+ self.__entity_name = None
9
+ self.__index = []
10
+ self.__primary = []
11
+ self.__unique = []
12
+
13
+ def best_sql_foreign_key(self):
14
+ elements = []
15
+ if self.__primary != []:
16
+ elements = self.__primary
17
+ elif self.__unique != []:
18
+ elements = self.__unique
19
+
20
+ if elements == []:
21
+ return None
22
+
23
+ reference_constraint = ReferenceConstraint()
24
+ reference_constraint.attributes = []
25
+ reference_constraint.references = self.__entity_name
26
+
27
+ foreign_key = ForeignKey()
28
+ foreign_key.attributes = []
29
+ foreign_key.reference = reference_constraint
30
+
31
+ index = Index()
32
+
33
+ data_types = []
34
+ for element in elements:
35
+ foreign_key.attributes.append(f"{self.__entity_name}_{element['name']}")
36
+ reference_constraint.attributes.append(element["name"])
37
+ index.add_attribute(f"{self.__entity_name}_{element['name']}")
38
+ data_types.append(element["data"]["type"])
39
+
40
+ return foreign_key, index, data_types
41
+
42
+ def from_code_writer_schema_context(
43
+ self, entity_name: str, index: list, primary: list, unique: list
44
+ ):
45
+ self.__entity_name = entity_name
46
+ self.__index = index
47
+ self.__primary = primary
48
+ self.__unique = unique
49
+ return self
@@ -0,0 +1,28 @@
1
+ from services.code.context.schema.DataDictionary import DataDictionary
2
+ from services.code.context.schema.EntityKeys import EntityKeys
3
+
4
+
5
+ class Manager:
6
+ def __init__(self):
7
+ self.__entity_keys_map = {}
8
+ self.data_dictionary = DataDictionary()
9
+ self.json = None
10
+
11
+ def from_code_writer_schema_context(self, context: dict):
12
+ self.data_dictionary.from_code_writer_schema_context(
13
+ context["data"]["dictionary"]
14
+ )
15
+
16
+ for entity_name, keys in context["keys"].items():
17
+ self.__entity_keys_map[
18
+ entity_name
19
+ ] = EntityKeys().from_code_writer_schema_context(
20
+ entity_name, keys["index"], keys["primary"], keys["unique"]
21
+ )
22
+
23
+ self.json = context
24
+
25
+ return self
26
+
27
+ def get_entity_keys(self, entity_name):
28
+ return self.__entity_keys_map.get(entity_name, None)
@@ -0,0 +1,8 @@
1
+ from services.code.context.schema.DataDictionary import DataDictionary
2
+
3
+
4
+ def test_configure():
5
+ data_dict = DataDictionary().from_code_writer_schema_context({"a": "b", "c": "d"})
6
+ assert data_dict.get_attribute_definition("z") is None
7
+ assert data_dict.get_attribute_definition("a") == "b"
8
+ assert data_dict.get_attribute_definition("c") == "d"
@@ -0,0 +1,52 @@
1
+ from services.code.context.schema.EntityKeys import EntityKeys
2
+ from structure.constraints.ReferenceConstraint import ReferenceConstraint
3
+ from structure.keys.ForeignKey import ForeignKey
4
+ from structure.keys.Index import Index
5
+
6
+
7
+ def test_best_sql_foreign_key_no_match():
8
+ assert EntityKeys().best_sql_foreign_key() is None
9
+
10
+
11
+ def test_best_sql_foreign_key_choose_primary():
12
+ ek = EntityKeys().from_code_writer_schema_context(
13
+ "abc",
14
+ [],
15
+ [
16
+ {"data": {"type": "pk_type_1"}, "name": "pk_name_1"},
17
+ {"data": {"type": "pk_type_2"}, "name": "pk_name_2"},
18
+ ],
19
+ [{"data": {"type": "uk_type_1"}, "name": "uk_name_1"}],
20
+ )
21
+
22
+ foreign_key, index, data_types = ek.best_sql_foreign_key()
23
+ assert isinstance(foreign_key, ForeignKey)
24
+ assert isinstance(foreign_key.reference, ReferenceConstraint)
25
+ assert isinstance(index, Index)
26
+ assert foreign_key.attributes == ["abc_pk_name_1", "abc_pk_name_2"]
27
+ assert foreign_key.reference.attributes == ["pk_name_1", "pk_name_2"]
28
+ assert foreign_key.reference.references == "abc"
29
+ assert len(index.attributes) == 2
30
+ assert index.attributes[0].name == "abc_pk_name_1"
31
+ assert index.attributes[1].name == "abc_pk_name_2"
32
+ assert len(data_types) == 2
33
+ assert data_types[0] == "pk_type_1"
34
+ assert data_types[1] == "pk_type_2"
35
+
36
+
37
+ def test_best_sql_foreign_key_choose_unique():
38
+ ek = EntityKeys().from_code_writer_schema_context(
39
+ "abc", [], [], [{"data": {"type": "uk_type_1"}, "name": "uk_name_1"}]
40
+ )
41
+
42
+ foreign_key, index, data_types = ek.best_sql_foreign_key()
43
+ assert isinstance(foreign_key, ForeignKey)
44
+ assert isinstance(foreign_key.reference, ReferenceConstraint)
45
+ assert isinstance(index, Index)
46
+ assert foreign_key.attributes == ["abc_uk_name_1"]
47
+ assert foreign_key.reference.attributes == ["uk_name_1"]
48
+ assert foreign_key.reference.references == "abc"
49
+ assert len(index.attributes) == 1
50
+ assert index.attributes[0].name == "abc_uk_name_1"
51
+ assert len(data_types) == 1
52
+ assert data_types[0] == "uk_type_1"
@@ -0,0 +1,34 @@
1
+ from services.code.context.schema.EntityKeys import EntityKeys
2
+ from services.code.context.schema.Manager import Manager
3
+
4
+
5
+ def test_get_entity_keys_no_such_entity_name():
6
+ assert Manager().get_entity_keys("abc") is None
7
+
8
+
9
+ def test_from_code_writer_schema_context_data_dictionary():
10
+ context = {"data": {"dictionary": {"abc": "def", "ghi": "jkl"}}, "keys": {}}
11
+
12
+ manager = Manager().from_code_writer_schema_context(context)
13
+ assert manager.data_dictionary.get_attribute_definition("abc") == "def"
14
+ assert manager.data_dictionary.get_attribute_definition("ghi") == "jkl"
15
+
16
+
17
+ def test_from_code_writer_schema_context_get_entity_keys():
18
+ context = {
19
+ "data": {"dictionary": {}},
20
+ "keys": {
21
+ "abc_def": {
22
+ "index": [],
23
+ "primary": [
24
+ {"data": {"type": "pk_type_1"}, "name": "pk_name_1"},
25
+ {"data": {"type": "pk_type_2"}, "name": "pk_name_2"},
26
+ ],
27
+ "unique": [],
28
+ }
29
+ },
30
+ }
31
+
32
+ manager = Manager().from_code_writer_schema_context(context)
33
+ assert manager.get_entity_keys("def_ghi") is None
34
+ assert isinstance(manager.get_entity_keys("abc_def"), EntityKeys)
@@ -0,0 +1,51 @@
1
+ import os
2
+
3
+ from core.Configuration import Configuration
4
+ from services.code.customization.BaseCustomization import BaseCustomization
5
+
6
+
7
+ class Authenticator(BaseCustomization):
8
+ def __init__(self, configuration: Configuration):
9
+ super().__init__(configuration)
10
+ self.__link_target = None
11
+ self.__file_contents = None
12
+
13
+ def __get_file_name(self):
14
+ return (
15
+ self.configuration.project.dev.api.path
16
+ + "/"
17
+ + self.configuration.project.dev.api.version
18
+ + "/Authenticator.py"
19
+ )
20
+
21
+ def preserve(self):
22
+ authenticator_file_name = self.__get_file_name()
23
+
24
+ if os.path.islink(authenticator_file_name):
25
+ self.__link_target = os.readlink(authenticator_file_name)
26
+ elif os.path.isfile(authenticator_file_name):
27
+ with open(authenticator_file_name, "r") as f:
28
+ self.__file_contents = f.read()
29
+
30
+ return self
31
+
32
+ def restore(self):
33
+ authenticator_file_name = self.__get_file_name()
34
+
35
+ if self.__link_target is not None:
36
+ try:
37
+ os.unlink(authenticator_file_name)
38
+ except FileNotFoundError:
39
+ pass
40
+
41
+ os.symlink(self.__link_target, authenticator_file_name)
42
+ elif self.__file_contents is not None:
43
+ try:
44
+ os.unlink(authenticator_file_name)
45
+ except FileNotFoundError:
46
+ pass
47
+
48
+ with open(authenticator_file_name, "w") as f:
49
+ f.write(self.__file_contents)
50
+
51
+ return self
@@ -0,0 +1,12 @@
1
+ from core.Configuration import Configuration
2
+
3
+
4
+ class BaseCustomization:
5
+ def __init__(self, configuration: Configuration):
6
+ self.configuration = configuration
7
+
8
+ def preserve(self):
9
+ raise NotImplementedError
10
+
11
+ def restore(self):
12
+ raise NotImplementedError
@@ -0,0 +1,20 @@
1
+ from core.Configuration import Configuration
2
+ from services.code.customization.Authenticator import Authenticator
3
+
4
+
5
+ class CustomizationManager:
6
+ def __init__(self, configuration: Configuration):
7
+ self.configuration = configuration
8
+ self.customizations = [Authenticator(self.configuration)]
9
+
10
+ def preserve(self):
11
+ for customization in self.customizations:
12
+ customization.preserve()
13
+
14
+ return self
15
+
16
+ def restore(self):
17
+ for customization in self.customizations:
18
+ customization.restore()
19
+
20
+ return self
@@ -0,0 +1,53 @@
1
+ import os
2
+ import shutil
3
+
4
+ from core.Configuration import Configuration
5
+ from services.code.customization.Authenticator import Authenticator
6
+
7
+
8
+ def test_link_target():
9
+ configuration = Configuration()
10
+ configuration.project.dev.api.path = "/tmp/gibsonai-unit-test"
11
+ configuration.project.dev.api.version = "v1"
12
+
13
+ try:
14
+ os.makedirs("/tmp/gibsonai-unit-test/v1")
15
+
16
+ os.symlink("/etc/passwd", "/tmp/gibsonai-unit-test/v1/Authenticator.py")
17
+
18
+ authenticator = Authenticator(configuration).preserve()
19
+ os.unlink("/tmp/gibsonai-unit-test/v1/Authenticator.py")
20
+ authenticator.restore()
21
+
22
+ assert os.path.islink("/tmp/gibsonai-unit-test/v1/Authenticator.py") is True
23
+ assert os.readlink("/tmp/gibsonai-unit-test/v1/Authenticator.py") == (
24
+ "/etc/passwd"
25
+ )
26
+ finally:
27
+ shutil.rmtree("/tmp/gibsonai-unit-test")
28
+
29
+
30
+ def test_file_contents():
31
+ configuration = Configuration()
32
+ configuration.project.dev.api.path = "/tmp/gibsonai-unit-test"
33
+ configuration.project.dev.api.version = "v1"
34
+
35
+ try:
36
+ os.makedirs("/tmp/gibsonai-unit-test/v1")
37
+
38
+ with open("/tmp/gibsonai-unit-test/v1/Authenticator.py", "w") as f:
39
+ f.write("abc def\nghi jkl")
40
+
41
+ authenticator = Authenticator(configuration).preserve()
42
+ os.unlink("/tmp/gibsonai-unit-test/v1/Authenticator.py")
43
+ assert os.path.islink("/tmp/gibsonai-unit-test/v1/Authenticator.py") is False
44
+ assert os.path.isfile("/tmp/gibsonai-unit-test/v1/Authenticator.py") is False
45
+ authenticator.restore()
46
+
47
+ assert os.path.islink("/tmp/gibsonai-unit-test/v1/Authenticator.py") is False
48
+ assert os.path.isfile("/tmp/gibsonai-unit-test/v1/Authenticator.py") is True
49
+
50
+ with open("/tmp/gibsonai-unit-test/v1/Authenticator.py", "r") as f:
51
+ assert f.read() == "abc def\nghi jkl"
52
+ finally:
53
+ shutil.rmtree("/tmp/gibsonai-unit-test")