Skip to content

Commit 0328831

Browse files
author
Johannes Hötter
committed
adds kern push, documentation and exceptions
1 parent 4ac63b5 commit 0328831

File tree

5 files changed

+93
-15
lines changed

5 files changed

+93
-15
lines changed

README.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,30 @@ An example export file looks like this:
7676
In this example, there is no manual label, but a weakly supervised label `"Negative"` has been set with 62.2% confidence.
7777

7878
### Fetch lookup lists
79-
- [ ] Todo
79+
In your project, you can create lookup lists to implement distant supervision heuristics. To fetch your lookup list(s), you can either get all or fetch one by its list id.
80+
```python
81+
list_id = "your-list-id"
82+
lookup_list = client.get_lookup_list(list_id)
83+
```
84+
85+
The list id can be found in your browser URL when you're on the details page of a lookup list, e.g. when you run on localhost: `http://localhost:4455/app/projects/{project_id}/knowledge-base/{list_id}`.
86+
87+
Alternatively, you can pull all lookup lists:
88+
```python
89+
lookup_lists = client.get_lookup_lists()
90+
```
8091

8192
### Upload files
82-
- [ ] Todo
93+
You can import files directly from your machine to your application:
94+
95+
```python
96+
file_path = "my/file/path/data.json"
97+
upload_was_successful = client.post_file_import(file_path)
98+
```
99+
100+
Alternatively, you can `kern push <path-to-your-file>` via CLI, given that you have provided the `secrets.json` file in the same directory.
101+
102+
**Make sure that you've selected the correct project beforehand, and fit the data schema of existing records in your project!**
83103

84104
### Adapters
85105

@@ -174,7 +194,8 @@ Let us know what open-source/closed-source NLP framework you are using, for whic
174194

175195
## Roadmap
176196
- [ ] Register heuristics via wrappers
177-
- [ ] Add project upload
197+
- [ ] Up/download zipped projects for versioning via DVC
198+
- [x] Add project upload
178199
- [x] Fetch project statistics
179200

180201

kern/__init__.py

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ def __init__(
3939

4040
@classmethod
4141
def from_secrets_file(cls, path_to_file: str):
42+
"""Creates a Client object from a secrets file.
43+
44+
Args:
45+
path_to_file (str): Path to the secrets file.
46+
47+
Returns:
48+
Client: kern.Client object.
49+
"""
4250
with open(path_to_file, "r") as file:
4351
content = json.load(file)
4452
uri = content.get("uri")
@@ -62,11 +70,24 @@ def get_project_details(self) -> Dict[str, str]:
6270
return api_response
6371

6472
def get_lookup_list(self, list_id: str) -> Dict[str, str]:
73+
"""Fetches a lookup list of your current project.
74+
75+
Args:
76+
list_id (str): The ID of the lookup list.
77+
78+
Returns:
79+
Dict[str, str]: Containing the specified lookup list of your project.
80+
"""
6581
url = settings.get_lookup_list_url(self.project_id, list_id)
6682
api_response = api_calls.get_request(url, self.session_token)
6783
return api_response
6884

6985
def get_lookup_lists(self) -> List[Dict[str, str]]:
86+
"""Fetches all lookup lists of your current project
87+
88+
Returns:
89+
List[Dict[str, str]]: Containing the lookups lists of your project.
90+
"""
7091
lookup_lists = []
7192
for lookup_list_id in self.get_project_details()["knowledge_base_ids"]:
7293
lookup_list = self.get_lookup_list(lookup_list_id)
@@ -128,14 +149,29 @@ def get_record_export(
128149
msg.good(f"Downloaded export to {download_to}")
129150
return df
130151

131-
def post_file_import(self, path: str) -> bool:
152+
def post_file_import(
153+
self, path: str, import_file_options: Optional[str] = ""
154+
) -> bool:
155+
"""Imports a file into your project.
156+
157+
Args:
158+
path (str): Path to the file to import.
159+
import_file_options (Optional[str], optional): Options for the Pandas import. Defaults to None.
160+
161+
Raises:
162+
FileImportError: If the file could not be imported, an exception is raised.
163+
164+
Returns:
165+
bool: True if the file was imported successfully, False otherwise.
166+
"""
132167
if not os.path.exists(path):
133-
raise Exception(f"Given filepath is not valid. Path: {path}")
168+
raise exceptions.FileImportError(
169+
f"Given filepath is not valid. Path: {path}"
170+
)
134171
last_path_part = path.split("/")[-1]
135172
file_name = f"{last_path_part}_SCALE"
136-
file_type = "records"
137-
import_file_options = ""
138173

174+
FILE_TYPE = "records"
139175
# config
140176
config_url = settings.get_base_config(self.project_id)
141177
config_api_response = api_calls.get_request(
@@ -150,7 +186,7 @@ def post_file_import(self, path: str) -> bool:
150186
credentials_url,
151187
{
152188
"file_name": file_name,
153-
"file_type": file_type,
189+
"file_type": FILE_TYPE,
154190
"import_file_options": import_file_options,
155191
},
156192
self.session_token,
@@ -171,4 +207,9 @@ def post_file_import(self, path: str) -> bool:
171207
path,
172208
file_name,
173209
)
174-
return True if success else False
210+
if success:
211+
msg.good(f"Uploaded {path} to your project.")
212+
return True
213+
else:
214+
msg.fail(f"Could not upload {path} to your project.")
215+
return False

kern/cli.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,20 @@ def pull():
1010
client.get_record_export(download_to=download_to)
1111

1212

13+
def push(file_path):
14+
client = Client.from_secrets_file("secrets.json")
15+
client.post_file_import(file_path)
16+
17+
1318
def help():
1419
msg.info(
15-
"With the Kern SDK, you can type commands as `kern <command>`. Currently, we provide the following:"
20+
"With the Kern refinery SDK, you can type commands as `kern <command>`. Currently, we provide the following:"
1621
)
1722
msg.info(
1823
"- kern pull: Download the record export of the project defined in `settings.json` to your local storage."
1924
)
2025
msg.info(
21-
"- kern push <path>: Upload a record file to the project defined in `settings.json` from your local storage. Currently in development."
26+
"- kern push <path>: Upload a record file to the project defined in `settings.json` from your local storage."
2227
)
2328

2429

@@ -33,7 +38,11 @@ def main():
3338
if command == "pull":
3439
pull()
3540
elif command == "push":
36-
msg.warn("Currently in development.")
41+
if len(cli_args) != 2:
42+
msg.fail("Please provide a path to a file when running kern push.")
43+
else:
44+
file_path = cli_args[1]
45+
push(file_path)
3746
elif command == "help":
3847
help()
3948
else:

kern/exceptions.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ class InternalServerError(SDKError):
2626
pass
2727

2828

29+
class FileImportError(Exception):
30+
pass
31+
32+
2933
RESPONSE_CODES_API_EXCEPTION_MAP = {
30-
401: UnauthorizedError,
31-
404: NotFoundError,
32-
500: InternalServerError,
34+
401: {"*": UnauthorizedError},
35+
404: {"*": NotFoundError},
36+
500: {"*": InternalServerError},
3337
}
3438

3539

setup.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@
3737
"python-dateutil==2.8.2",
3838
"pytz==2022.1",
3939
"requests==2.27.1",
40+
"boto3==1.24.26",
41+
"botocore==1.27.26",
4042
"six==1.16.0",
43+
"spacy==3.3.1",
4144
"tinycss2==1.1.1",
4245
"tomli==2.0.1",
4346
"typing_extensions==4.2.0",

0 commit comments

Comments
 (0)