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
core/Memory.py ADDED
@@ -0,0 +1,148 @@
1
+ import json
2
+ import os
3
+
4
+ from .Configuration import Configuration
5
+
6
+
7
+ class Memory:
8
+ def __init__(self, configuration: Configuration):
9
+ self.configuration = configuration
10
+ self.entities = None
11
+ self.last = None
12
+ self.bootstrap()
13
+
14
+ def append_last(self, entity: dict):
15
+ if self.last is None:
16
+ self.last = {"entities": []}
17
+
18
+ self.last["entities"].append(entity)
19
+ self.remember_last(self.last)
20
+
21
+ return self
22
+
23
+ def bootstrap(self):
24
+ self.__make_memory_dir()
25
+ self.entities = self.recall_entities()
26
+ self.last = self.recall_last()
27
+
28
+ def __forget(self, file):
29
+ try:
30
+ os.remove(file)
31
+ except FileNotFoundError:
32
+ pass
33
+
34
+ return self
35
+
36
+ def forget_entities(self):
37
+ self.__forget(self.get_path_entities())
38
+ return self
39
+
40
+ def forget_last(self):
41
+ self.__forget(self.get_path_last())
42
+ return self
43
+
44
+ def __recall(self, file):
45
+ try:
46
+ with open(file, "r") as f:
47
+ contents = f.read()
48
+ except FileNotFoundError:
49
+ return None
50
+
51
+ return json.loads(contents)
52
+
53
+ def recall_entities(self):
54
+ return self.__recall(self.get_path_entities())
55
+
56
+ def recall_entity(self, name):
57
+ entity = self.recall_last_entity(name)
58
+ if entity is not None:
59
+ return entity
60
+
61
+ entity = self.recall_stored_entity(name)
62
+ if entity is not None:
63
+ return entity
64
+
65
+ return None
66
+
67
+ def recall_last(self):
68
+ return self.__recall(self.get_path_last())
69
+
70
+ def recall_last_entity(self, name):
71
+ if self.last is not None:
72
+ for entity in self.last["entities"]:
73
+ if entity["name"] == name:
74
+ return entity
75
+ return None
76
+
77
+ def recall_merged(self):
78
+ if self.entities is None:
79
+ if self.last is not None:
80
+ return self.last["entities"]
81
+ else:
82
+ return []
83
+
84
+ entities = []
85
+ last_map = {}
86
+ if self.last is not None:
87
+ for entry in self.last["entities"]:
88
+ last_map[entry["name"]] = True
89
+ entities.append(entry)
90
+
91
+ for entry in self.entities:
92
+ if entry["name"] not in last_map:
93
+ entities.append(entry)
94
+
95
+ return entities
96
+
97
+ def recall_stored_entity(self, name):
98
+ if self.entities is not None:
99
+ for entity in self.entities:
100
+ if entity["name"] == name:
101
+ return entity
102
+
103
+ return None
104
+
105
+ def __remember(self, file, data):
106
+ with open(file, "w") as f:
107
+ f.write(json.dumps(data))
108
+
109
+ return self
110
+
111
+ def remember_entities(self, entities: list):
112
+ self.__remember(self.get_path_entities(), entities)
113
+ return self
114
+
115
+ def remember_last(self, data: dict):
116
+ self.__remember(self.get_path_last(), data)
117
+ return self
118
+
119
+ def get_path_entities(self):
120
+ return self.get_path_top() + "/entities"
121
+
122
+ def get_path_last(self):
123
+ return self.get_path_top() + "/last"
124
+
125
+ def get_path_top(self):
126
+ return (
127
+ self.configuration.project.paths.memory
128
+ + "/"
129
+ + self.configuration.project.name
130
+ )
131
+
132
+ def __make_memory_dir(self):
133
+ try:
134
+ os.mkdir(self.get_path_top())
135
+ except FileExistsError:
136
+ pass
137
+
138
+ def stats(self):
139
+ num_entities = len(self.entities) if self.entities is not None else 0
140
+ num_last = len(self.last["entities"]) if self.last is not None else 0
141
+
142
+ return {
143
+ "entities": {"num": num_entities, "word": self.word_entities(num_entities)},
144
+ "last": {"num": num_last, "word": self.word_entities(num_last)},
145
+ }
146
+
147
+ def word_entities(self, num):
148
+ return "entities" if num == 0 or num > 1 else "entity"
core/TimeKeeper.py ADDED
@@ -0,0 +1,12 @@
1
+ import time
2
+
3
+
4
+ class TimeKeeper:
5
+ def __init__(self):
6
+ self.__started = time.time()
7
+
8
+ def display(self):
9
+ print(self.get_display() + "\n")
10
+
11
+ def get_display(self):
12
+ return "[%ss]" % str(time.time() - self.__started)[0:7]
core/utils.py ADDED
@@ -0,0 +1,19 @@
1
+ def utils_entity_name_to_class_name(entity_name):
2
+ parts = entity_name.split("_")
3
+
4
+ name = []
5
+ for part in parts:
6
+ name.append(part.title())
7
+
8
+ return "".join(name)
9
+
10
+
11
+ def utils_extract_module_name(entity_name):
12
+ return entity_name.split("_")[0]
13
+
14
+
15
+ def utils_is_ref_table(entity_name):
16
+ try:
17
+ return entity_name.split("_")[1] == "ref"
18
+ except IndexError:
19
+ return False
@@ -0,0 +1,4 @@
1
+ create table $entity_name(
2
+ id bigint not null auto_increment primary key,
3
+ value varchar(100) default null unique
4
+ )
@@ -0,0 +1,6 @@
1
+ create table $entity_name(
2
+ id bigint not null auto_increment primary key,
3
+ uuid varchar(36) not null unique,
4
+ date_created datetime not null default current_timestamp,
5
+ date_updated datetime default null on update current_timestamp
6
+ )
db/TableExceptions.py ADDED
@@ -0,0 +1,6 @@
1
+ class TableExceptions:
2
+ def mysql(self):
3
+ return self.universal()
4
+
5
+ def universal(self):
6
+ return ["alembic_version"]
@@ -0,0 +1,9 @@
1
+ from db.TableExceptions import TableExceptions
2
+
3
+
4
+ def test_universal():
5
+ assert TableExceptions().universal() == ["alembic_version"]
6
+
7
+
8
+ def test_mysql():
9
+ assert TableExceptions().mysql() == ["alembic_version"]
dev/Dev.py ADDED
@@ -0,0 +1,92 @@
1
+ import os
2
+
3
+ from core.Configuration import Configuration
4
+ from core.utils import (
5
+ utils_entity_name_to_class_name,
6
+ utils_extract_module_name,
7
+ utils_is_ref_table,
8
+ )
9
+
10
+
11
+ class Dev:
12
+ def __init__(self, configuration: Configuration):
13
+ self.configuration = configuration
14
+
15
+ def api_component(self, file_name, code):
16
+ self.__write_code(
17
+ self.configuration.project.dev.api.path,
18
+ f"{self.configuration.project.dev.api.version}/{file_name}",
19
+ code,
20
+ )
21
+
22
+ if file_name == "authenticators/DenyAll.py":
23
+ self.link(
24
+ os.path.expandvars(self.configuration.project.dev.api.path),
25
+ self.configuration.project.dev.api.version
26
+ + "/authenticators/DenyAll.py",
27
+ self.configuration.project.dev.api.version + "/Authenticator.py",
28
+ )
29
+
30
+ return self
31
+
32
+ def base_component(self, file_name, code):
33
+ self.__write_code(self.configuration.project.dev.base.path, file_name, code)
34
+
35
+ def link(self, base_path, source_file, target_file, overwrite=False):
36
+ target = f"{base_path}/{target_file}"
37
+ if overwrite is False:
38
+ if os.path.isfile(target):
39
+ return self
40
+
41
+ os.symlink(f"{base_path}/{source_file}", target)
42
+
43
+ return self
44
+
45
+ def __mkdirs(self, path):
46
+ os.makedirs(path, exist_ok=True)
47
+ return path
48
+
49
+ def model(self, entity_name, code):
50
+ if utils_is_ref_table(entity_name) is True:
51
+ return self
52
+
53
+ module = utils_extract_module_name(entity_name)
54
+ file = utils_entity_name_to_class_name(entity_name) + ".py"
55
+
56
+ return self.__write_code(
57
+ self.configuration.project.dev.model.path, f"{module}/{file}", code
58
+ )
59
+
60
+ def schema(self, entity_name, code):
61
+ if utils_is_ref_table(entity_name) is True:
62
+ return self
63
+
64
+ module = utils_extract_module_name(entity_name)
65
+ file = utils_entity_name_to_class_name(entity_name) + ".py"
66
+
67
+ return self.__write_code(
68
+ self.configuration.project.dev.schema.path,
69
+ f"{module}/{file}",
70
+ code,
71
+ )
72
+
73
+ def tests(self, entity_name, code):
74
+ if utils_is_ref_table(entity_name) is True:
75
+ return self
76
+
77
+ module = utils_extract_module_name(entity_name)
78
+ file = "test_" + utils_entity_name_to_class_name(entity_name) + "Base.py"
79
+
80
+ return self.__write_code(
81
+ self.configuration.project.dev.model.path, f"{module}/tests/{file}", code
82
+ )
83
+
84
+ def __write_code(self, path, file, code):
85
+ if self.configuration.project.dev.active is True:
86
+ full_path = f"{os.path.expandvars(path)}/{file}"
87
+
88
+ self.__mkdirs("/".join(full_path.split("/")[0:-1]))
89
+ with open(full_path, "w") as f:
90
+ f.write(code)
91
+
92
+ return self
display/Header.py ADDED
@@ -0,0 +1,6 @@
1
+ class Header:
2
+ def render(self, text):
3
+ header = "+--------------------------------------------------------------+\n"
4
+ header += "| " + text + " " * (61 - len(text)) + "|\n"
5
+ header += "+--------------------------------------------------------------+"
6
+ return header
@@ -0,0 +1,10 @@
1
+ class WorkspaceFooter:
2
+ def render(self):
3
+ return (
4
+ "=" * 79
5
+ + "\n"
6
+ + "[. + enter = exit] "
7
+ + "[:q + enter = abort] "
8
+ + "[:w + enter = merge + write code]\n"
9
+ + "Using natural language, tell me how I can modify this entity."
10
+ )
@@ -0,0 +1,8 @@
1
+ class WorkspaceHeader:
2
+ def render(self, project_name):
3
+ return (
4
+ f"Workspace {project_name}".ljust(50)
5
+ + " " * 13
6
+ + "[CONTEXT LOADED]\n"
7
+ + "=" * 79
8
+ )
@@ -0,0 +1,9 @@
1
+ from display.Header import Header
2
+
3
+
4
+ def test_render():
5
+ assert Header().render("abc def ghi") == (
6
+ """+--------------------------------------------------------------+
7
+ | abc def ghi |
8
+ +--------------------------------------------------------------+"""
9
+ )
@@ -0,0 +1,9 @@
1
+ from display.WorkspaceFooter import WorkspaceFooter
2
+
3
+
4
+ def test_render():
5
+ assert WorkspaceFooter().render() == (
6
+ """===============================================================================
7
+ [. + enter = exit] [:q + enter = abort] [:w + enter = merge + write code]
8
+ Using natural language, tell me how I can modify this entity."""
9
+ )
@@ -0,0 +1,8 @@
1
+ from display.WorkspaceHeader import WorkspaceHeader
2
+
3
+
4
+ def test_render():
5
+ assert WorkspaceHeader().render("abc def ghi") == (
6
+ """Workspace abc def ghi [CONTEXT LOADED]
7
+ ==============================================================================="""
8
+ )
@@ -0,0 +1,306 @@
1
+ Metadata-Version: 2.1
2
+ Name: gibson-cli
3
+ Version: 0.1.0
4
+ Summary: Gibson Command Line Interface
5
+ Author-email: GibsonAI <noc@gibsonai.com>
6
+ Project-URL: Homepage, https://gibsonai.com/
7
+ Classifier: Operating System :: OS Independent
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Gibson CLI
15
+
16
+ v.0.1.0
17
+
18
+ ## Prerequisites
19
+
20
+ Gibson currently works on projects that use Python 3.9 or greater, MySQL, SQLAlchemy, Pydantic, Alembic, FastAPI and pytest. It is capable of building a complete application, from database to API end points, using these frameworks. Future enhancements of Gibson will include support for more languages and frameworks.
21
+
22
+ Portions of the Gibson backend code are written by Gibson. So far, versus a human developer, it has coded 66% of the software and did so in seconds. To get started, read the instructions here.
23
+
24
+ ## Installation
25
+
26
+ - Clone this repository somewhere in your environment
27
+ - Modify your `PYTHONPATH` to include a reference to the top level directory here
28
+ - `pip3 install -r requirements.txt`
29
+ - Add the `bin/` directory to your `PATH`
30
+
31
+ ## Key Terms
32
+
33
+ - Dev Mode
34
+ - Turn dev mode on to have Gibson write code for you as you execute commands.
35
+
36
+ - Entity | Entities
37
+ - Synonymous with a table name or data structure.
38
+
39
+ - Memory
40
+ - There are two types of memory: stored (long term) and last (the last action taken).
41
+
42
+ - Merge
43
+ - Merge the entities in the last memory into the stored memory.
44
+
45
+ ## Memory Concepts
46
+
47
+ There are two types of memory maintained by the Gibson CLI:
48
+
49
+ - `stored` (long term)
50
+ - `last` (short term)
51
+
52
+ When you import a datastore or API project into Gibson it stores the schema and all of its entities in stored memory. Stored memory is long term. It contains a copy of your database schema and represents the currently stable version of it.
53
+
54
+ Each time you ask Gibson to do something that results in a new or modified entity it will store it in last memory. Any time you ask the CLI to perform a coding task it will prefer last memory first, then stored memory.
55
+
56
+ Let's consider a more concrete example. You imported your datastore into the CLI and one of the tables is called "user". You execute:
57
+
58
+ `gibson modify user I want to add nickname`
59
+
60
+ So Gibson creates a new version of the user table containing a nickname column. This new table is stored in last memory. If you execute:
61
+
62
+ `gibson models`
63
+
64
+ The CLI will write the code for what is sitting in last memory.
65
+
66
+ This means you can make changes, try things out and decide if you want to make the changes permanent before merging the changes from last to stored. You can easily forget the last changes you made by executing:
67
+
68
+ `gibson forget last`
69
+
70
+ When you're ready to commit, just execute:
71
+
72
+ `gibson merge`
73
+
74
+ Everything in last will be moved to stored and last will be forgotten. Finally, if you want Gibson to recreate your database schema with all the recent changes, just execute:
75
+
76
+ `gibson build datastore`
77
+
78
+ Just note, build will first drop all of the tables in the datastore then recreate the database from scratch.
79
+
80
+ ## Logging in
81
+
82
+ Run `gibson auth login` to login to Gibson with your Google account.
83
+
84
+ ## Acquiring an API Key
85
+
86
+ While in beta, you have to acquire an API manually:
87
+
88
+ - Go to <https://staging.gibsonai.com/>.
89
+ - Chat with Gibson and create a new project.
90
+ - When your project is complete Gibson will email you the API key.
91
+ - gibson conf api::key [API key]
92
+
93
+ ## Usage
94
+
95
+ The main command is located in `bin/gibson`. Executing this command with no parameters will provide a help style menu to guide you.
96
+
97
+ ## Configuration
98
+
99
+ All of Gibson's configuration files and caches are stored in `$HOME/.gibson`. Use `gibson conf` for updating the configuration and `gibson forget` for clearing caches.
100
+
101
+ ### For Windows Users
102
+
103
+ - Make sure that you have an environment variable called HOME set. Gibson will store its configuration files and caches in this directory. We recommend you keep this directory outside of any repository to which you might be committing.
104
+ - To execute the `gibson` command, follow these instructions:
105
+ - Assuming the gibson executable is in `c:\Users\\[me]\projects\gibson\bin`
106
+ - Run `python c:\Users\\[me]\projects\gibson\bin\gibson`
107
+
108
+ ## Editor Integration
109
+
110
+ ### vim
111
+
112
+ - Make sure the `gibson` command is in your path by editing the `PATH` environment variable
113
+ - Edit `~/.vimrc`
114
+ - Add the following:
115
+ - `:command! -nargs=* Gibson r ! gibson <args>`
116
+ - Open a file and execute commands:
117
+ - `:Gibson module abc`
118
+ - `:Gibson models`
119
+ - `:Gibson schemas`
120
+
121
+ ## Currently Supported Software
122
+
123
+ - Python 3.9 or greater
124
+ - MySQL
125
+ - SQLAlchemy
126
+ - Pydantic
127
+ - Alembic
128
+ - FastAPI
129
+ - pytest
130
+
131
+ More languages and frameworks are in active development. If you do not see a version that you need let us know and we will get on it.
132
+
133
+ ## Coming Very Soon
134
+
135
+ - pytest based unit tests for all of the code Gibson writes.
136
+ - We know this is critical for Gibson to prove that its code is production-grade and bug free. As a development team, we need this too. It is coming in short order.
137
+ - Enhanced AI commands at your finger tips with code output and scratch storage.
138
+ - [DONE] See "Asking Gibson Questions With Context"
139
+ - Context aware coding from your Github repository.
140
+ - gibson scan
141
+ - AI based feedback directly to Gibson's creator:
142
+ - `gibson tell mike [hopefully nice things]`
143
+ - e.g. `gibson tell mike we need support for postgres`
144
+ - or, `gibson tell mike to hire me, I want to work on gibson`
145
+ - Significant data modeling improvements.
146
+ - The ability to integrate and download Function code using `gibson`.
147
+ - Along with a number of new Functions.
148
+ - Full FastAPI coding including module and entity specific dispatchers.
149
+
150
+ ## Detailed How-To
151
+
152
+ ### First Step
153
+
154
+ - Just run `gibson`. He will say hello and walk you through set up.
155
+
156
+ ### Configuring Your API Key
157
+
158
+ `gibson conf api::key [API key]`
159
+
160
+ ### Configuring Your Datastore
161
+
162
+ `gibson conf datastore::uri mysql+pymysql://[user]:[password]@[host]/[database name]`
163
+
164
+ Note: Gibson currently only supports MySQL. Let us know if you need something else.
165
+
166
+ ### Turning On Dev Mode
167
+
168
+ `gibson dev on`
169
+
170
+ - We suggest you turn dev mode on and leave it on. With it enabled, Gibson will act like your coworker and write code as you execute commands.
171
+
172
+ - You will need to provide 3 paths: `base` (where you want project base code to go), `model` (where you want SQLAlchemy models to go) and `schema` (where you want Pydantic schemas to go).
173
+
174
+ ### Importing Your Datastore
175
+
176
+ `gibson import datastore`
177
+
178
+ - This will make Gibson's stored memory aware of all of your datastore objects.
179
+ - `gibson import datastore .. dev`
180
+ - In addition to making Gibson aware, this will write all of the base, model and schema code for you.
181
+
182
+ ### Configuring a Custom BaseModel
183
+
184
+ You may be using a custom SQLAlchemy BaseModel and you do not want Gibson to use the one it has written.
185
+
186
+ ```sh
187
+ gibson conf code::custom::model::class [class name]
188
+ gibson conf code::custom::path [import path]
189
+ ```
190
+
191
+ For example, you might provide class name = `MyBaseModel` and import path = `project.model.MyBaseModel`
192
+
193
+ ### Writing the Base Code
194
+
195
+ `gibson base`
196
+
197
+ ### Writing the Code for a Single Model
198
+
199
+ `gibson model [table name]`
200
+
201
+ ### Writing the Code for a Single Schema
202
+
203
+ `gibson schema [table name]`
204
+
205
+ ### Writing the Code for All Models
206
+
207
+ `gibson models`
208
+
209
+ ### Writing the Code for All Schemas
210
+
211
+ `gibson schemas`
212
+
213
+ ### Adding a New Module to the Software Using AI
214
+
215
+ - gibson module [module name]
216
+ - e.g. gibson module user
217
+ - Gibson will display the SQL tables it has generated as a result of your request. It will store these entities in its last memory.
218
+ - gibson models
219
+ - This will write the code for the entities it just created.
220
+ - gibson merge
221
+ - This will merge the new entities into your project.
222
+ - Note, at the moment Gibson does not build the tables into your datastore.
223
+
224
+ ### Making Changes to the Software Using AI
225
+
226
+ - `gibson modify [table name] [natural language request]`
227
+ - e.g. `gibson modify my_table I want to add a new column called name and remove all of the columns related to email`
228
+ - Gibson will display the modified SQL table and store it in its last memory.
229
+ - `gibson models`
230
+ - This will write the code for the modified entity.
231
+ - `gibson merge`
232
+ - This will merge the modified entity into your project.
233
+ - Note, at the moment Gibson does not build the modified table into your datastore.
234
+
235
+ ### Forgetting Things Stored in Memory
236
+
237
+ - `gibson forget stored`
238
+ - `gibson forget last`
239
+ - `gibson forget all`
240
+
241
+ ### Building All of the Entities in Stored Memory into the Datastore
242
+
243
+ `gibson build`
244
+
245
+ ### Showing an Entity that is Stored in Memory
246
+
247
+ `gibson show [entity name]`
248
+
249
+ ### Building a Project End-to-End Using AI
250
+
251
+ - Go to <https://staging.gibsonai.com/>.
252
+ - Chat with Gibson and create a new project.
253
+ - When your project is complete Gibson will email you the API key.
254
+ - `gibson conf api::key [API key]`
255
+ - `gibson import api .. dev`
256
+ - Magic, no?
257
+
258
+ ### Integrating a Model into Your Code
259
+
260
+ Gibson creates base-level SQLAlchemy models. To integrate them just do this:
261
+
262
+ ```py
263
+ from my_project.gibsonai.model.Module import ModuleBase
264
+
265
+ class MyModule(ModuleBase):
266
+ pass
267
+ ```
268
+
269
+ - When you need to add custom business logic to the model, just modify your version of the model:
270
+
271
+ ```py
272
+ from my_project.gibsonai.model.Module import ModuleBase
273
+
274
+ class MyModule(ModuleBase):
275
+ def my_custom_business_logic(self):
276
+ return 1 + 1
277
+ ```
278
+
279
+ We strongly suggest you do not reference the base-level SQLAlchemy models directly. By sub-classing you won't have to refactor your code if you decide to add custom code.
280
+
281
+ ### Integrating a Schema into Your Code
282
+
283
+ At the moment, just refer to the base-level schema directly.
284
+
285
+ ### Migrating Your Software from PHP to Python
286
+
287
+ - Configure your datastore.
288
+ - Turn on Dev Mode.
289
+ - `gibson import datastore .. dev`
290
+ - 70% of your code is written, customize the remaining.
291
+
292
+ ### Asking Gibson Questions With Context
293
+
294
+ - `gibson ? [natural language request]`
295
+ - Your natural language request can include:
296
+ - `file://[full path]` to import a file from the filesystem
297
+ - `py://[import]` to import a file from `PYTHONPATH`
298
+ - `sql://[entity name]` to import the SQL
299
+ - For example:
300
+ - `gibson ? format file:///Users/me/file.py for PEP8`
301
+ - `gibson ? code review py://user.modules.User`
302
+ - `gibson ? add nickname to sql://user`
303
+ - When using `sql://`, any entities that are created as part of Gibson's response will be transferred into Gibson's last memory allowing you to execute a question, create a new entity and have Gibson immediately create a model or schema from it.
304
+ - e.g. `gibson ? add nickname to sql://user`
305
+ - `gibson model`
306
+ - Important note, `gibson ?` may cause your shell to incorrectly interpret the question mark. If it does, you can use `gibson q` instead (just replace the question mark with the letter `q`).