Skip to content

Commit

Permalink
Merge pull request #2 from UCSD-E4E/core_dev
Browse files Browse the repository at this point in the history
feat: Core implementation
  • Loading branch information
ntlhui authored Nov 11, 2024
2 parents b874af5 + 0eeea65 commit 9ff3701
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -267,3 +267,4 @@ $RECYCLE.BIN/
*.lnk

# End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,windows,linux,macos
config.json
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"ms-toolsai.jupyter",
"njpwerner.autodocstring",
"ms-python.isort",
"ms-python.autopep8"
]
}
19 changes: 8 additions & 11 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@
"version": "0.2.0",
"configurations": [
{
"name": "Python: Run Module",
"type": "python",
"name": "Run Launch",
"type": "debugpy",
"request": "launch",
"module": "examplePackage.exampleModule",
"justMyCode": true
},
{
"name": "Python: Run File",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/examplePackage/exampleModule.py",
"program": "${workspaceFolder}/label_studio_slack_reporter/main.py",
"console": "integratedTerminal",
"justMyCode": true
"justMyCode": true,
"args": [
"--config",
"${workspaceFolder}/config.json"
]
}
]
}
8 changes: 6 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
"tests"
],
"python.testing.unittestEnabled": false,
"python.linting.pylintEnabled": true,
"editor.rulers": [
100
]
],
"python.testing.pytestEnabled": true,
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "modifications",
"editor.formatOnType": true
}
7 changes: 7 additions & 0 deletions example_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label_studio_key": "abcdef1234",
"label_studio_url": "https://labeler.e4e.ucsd.edu",
"label_studio_project_id": 10,
"slack_client_secret": "xoxb-abcdef1234",
"slack_channel_id": "abcdef1234"
}
95 changes: 93 additions & 2 deletions label_studio_slack_reporter/main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,101 @@
'''Label Studio Slack Reporter
'''
import argparse
import json
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Dict, List

from label_studio_sdk.client import LabelStudio
from label_studio_sdk.types import BaseUser
from label_studio_sdk.projects.client_ext import ProjectExt
from slack_sdk import WebClient


def main() -> None:
"""Main Entry Point
"""

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', type=Path)

args = parser.parse_args()

with open(args.config, 'r', encoding='utf-8') as handle:
config_params = json.load(handle)

ls_client = LabelStudio(
base_url=config_params['label_studio_url'], api_key=config_params['label_studio_key'])

project_id = config_params['label_studio_project_id']
export = get_project_export(ls_client, project_id)
user_list = ls_client.users.list()
project_info = ls_client.projects.get(
id=project_id)
annotations_count: Dict[int, int] = {user.id: 0 for user in user_list}
for task in export:
for annotation in task['annotations']:
annotations_count[annotation['completed_by']] += 1

message = generate_message(user_list, project_info, annotations_count)

slack_client = WebClient(token=config_params['slack_client_secret'])
slack_client.chat_postMessage(
channel=config_params['slack_channel_id'],
text=message
)


def generate_message(user_list: List[BaseUser],
project_info: ProjectExt,
annotations_count: Dict[int, int]) -> str:
"""Generates message
Args:
user_list (List[BaseUser]): List of users
project_info (ProjectExt): Project info
annotations_count (Dict[int, int]): List of annotations
Returns:
str: Formatted message
"""
message = f'Results for {project_info.title}\n'
for user in sorted(user_list, key=lambda x: annotations_count[x.id], reverse=True):
if not user.id in annotations_count:
count = 0
else:
count = annotations_count[user.id]
message += f'{user.email}: {count}\n'

message += f'Total: {sum(annotations_count.values())}'
return message


def get_project_export(ls_client: LabelStudio, project_id: int) -> Dict:
"""Retrieves the project export
Args:
ls_client (LabelStudio): LabelStudio client
project_id (int): Project to export
Returns:
Dict: LabelStudio project export
"""
response = ls_client.projects.exports.create_export(
id=project_id,
export_type='JSON',
download_all_tasks=False,
download_resources=False
)
with TemporaryDirectory() as tmpdir:
temp_dir = Path(tmpdir)
temp_file = temp_dir / 'export.json'
with open(temp_file, 'wb') as handle:
for blob in response:
handle.write(blob)
with open(temp_file, 'r', encoding='utf-8') as handle:
export = json.load(handle)
return export


if __name__ == "__main__":
if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ repository = 'https://github.com/UCSD-E4E/label-studio-slack-reporter'
python = "^3.12"
label-studio-sdk = "^1.0.7"
slack-sdk = "^3.33.3"
platformdirs = "^4.3.6"

[tool.poetry.group.dev.dependencies]
pylint = "^3.2.7"
Expand Down

0 comments on commit 9ff3701

Please sign in to comment.