Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add module config for module_example and module_text_llm #44

Merged
merged 97 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
a6dc85d
add llm config
FelixTJDietrich Jul 4, 2023
52af88a
add other changes
FelixTJDietrich Jul 4, 2023
f75b3e1
commiting before it is too late
FelixTJDietrich Jul 6, 2023
b13d52e
hitting save
FelixTJDietrich Jul 6, 2023
c18223e
fix openai langchain credentials
FelixTJDietrich Jul 7, 2023
69023e1
add openai config options
FelixTJDietrich Jul 7, 2023
12259fa
remove unused import
FelixTJDietrich Jul 7, 2023
60b359d
add get_model
FelixTJDietrich Jul 7, 2023
f424fad
fix type error
FelixTJDietrich Jul 7, 2023
f361a10
remove line
FelixTJDietrich Jul 7, 2023
19284b1
allow module get requests
FelixTJDietrich Jul 8, 2023
0b6140b
add config to example
FelixTJDietrich Jul 8, 2023
fd4fbeb
add configuration ui
FelixTJDietrich Jul 8, 2023
e6fe5e9
get config
FelixTJDietrich Jul 8, 2023
31aa180
fix fetcher
FelixTJDietrich Jul 8, 2023
8beaa2d
improving config
FelixTJDietrich Jul 8, 2023
4fdbeea
update example config
FelixTJDietrich Jul 8, 2023
c48809d
add unstyled form template
FelixTJDietrich Jul 8, 2023
d64df8a
another workaround
FelixTJDietrich Jul 9, 2023
089beba
update styles
FelixTJDietrich Jul 9, 2023
7fb0646
add some markdown
FelixTJDietrich Jul 9, 2023
dab178e
fix styling
FelixTJDietrich Jul 9, 2023
ec8ac95
remove form again
FelixTJDietrich Jul 9, 2023
01db885
add reset button again
FelixTJDietrich Jul 9, 2023
1b99826
change error position
FelixTJDietrich Jul 9, 2023
0db6c5b
get module_config in module endpoints
FelixTJDietrich Jul 9, 2023
1760533
add metadata and fix stuff
FelixTJDietrich Jul 9, 2023
19a78c1
fix playground response views
FelixTJDietrich Jul 9, 2023
2e43a2d
use module config in example
FelixTJDietrich Jul 9, 2023
af2347c
rename config provider
FelixTJDietrich Jul 9, 2023
c4f2de6
rename route
FelixTJDietrich Jul 9, 2023
385a5bc
add prompt config
FelixTJDietrich Jul 10, 2023
aa5cd30
fix config and use config in llm module
FelixTJDietrich Jul 10, 2023
44d8d10
fix credentials
FelixTJDietrich Jul 10, 2023
e1f826c
update env
FelixTJDietrich Jul 10, 2023
cc9b84b
rename to config schema
FelixTJDietrich Jul 10, 2023
3db5f60
add changes
FelixTJDietrich Jul 10, 2023
acee861
add cool stuff
FelixTJDietrich Jul 10, 2023
0e9f8a3
change prompt field and auto submit
FelixTJDietrich Jul 11, 2023
cf2d0c1
fix checkbox
FelixTJDietrich Jul 11, 2023
6ac9759
fix styles and reset
FelixTJDietrich Jul 11, 2023
30d90d4
refactor form
FelixTJDietrich Jul 11, 2023
c456c78
improve code structure
FelixTJDietrich Jul 11, 2023
04b832b
add markdown comments
FelixTJDietrich Jul 11, 2023
77013fd
fix comments
FelixTJDietrich Jul 11, 2023
6e5aac0
remove console log
FelixTJDietrich Jul 11, 2023
3dbbe8e
add default config schema renderer
FelixTJDietrich Jul 11, 2023
ba45cbf
delete unused
FelixTJDietrich Jul 11, 2023
6230a5b
fix chat models
FelixTJDietrich Jul 11, 2023
7094690
fix formatting and remove unused
FelixTJDietrich Jul 11, 2023
eb32096
change small issues
FelixTJDietrich Jul 11, 2023
53aaf12
delete file
FelixTJDietrich Jul 11, 2023
9ea2dfd
fix minor issues
FelixTJDietrich Jul 11, 2023
00b3ed7
remove unused packages
FelixTJDietrich Jul 11, 2023
387fa1c
fix send feedback
FelixTJDietrich Jul 11, 2023
6bb7542
fix stuff
FelixTJDietrich Jul 11, 2023
eb2f949
fix meta strange nesting
FelixTJDietrich Jul 13, 2023
4195019
fix args
FelixTJDietrich Jul 13, 2023
e85ed87
improve metadata
FelixTJDietrich Jul 13, 2023
4b5e6f9
add comment
FelixTJDietrich Jul 13, 2023
c7aea15
add usage example
FelixTJDietrich Jul 13, 2023
7b32eb6
change order
FelixTJDietrich Jul 13, 2023
d7fbc4f
update module_text_llm/module_text_llm/config.py
FelixTJDietrich Jul 13, 2023
702bae9
improve config stuff
FelixTJDietrich Jul 13, 2023
a02e135
update docs
FelixTJDietrich Jul 13, 2023
192b380
improve config
FelixTJDietrich Jul 14, 2023
9cda190
add comments and fix
FelixTJDietrich Jul 14, 2023
4c451a2
add suggestion
FelixTJDietrich Jul 14, 2023
e83934e
simplify
FelixTJDietrich Jul 14, 2023
8735634
simplify
FelixTJDietrich Jul 14, 2023
0c689e4
update model
FelixTJDietrich Jul 14, 2023
1252a7b
remove undefined
FelixTJDietrich Jul 14, 2023
19fbade
add source note
FelixTJDietrich Jul 14, 2023
4d10934
add comment
FelixTJDietrich Jul 14, 2023
70c7c7f
add documentation
FelixTJDietrich Jul 14, 2023
db47dc0
fix stuff
FelixTJDietrich Jul 14, 2023
499d38e
add fixes
FelixTJDietrich Jul 14, 2023
d0a6a79
fix typing
FelixTJDietrich Jul 14, 2023
ada0c49
fix error
FelixTJDietrich Jul 14, 2023
38c37da
move code to the right place
FelixTJDietrich Jul 16, 2023
ddb4994
Update assessment_module_manager/assessment_module_manager/module/req…
FelixTJDietrich Jul 17, 2023
38ee7fd
Merge branch 'develop' of https://github.com/ls1intum/athena into fea…
FelixTJDietrich Jul 17, 2023
dd5624b
change T to D for data
FelixTJDietrich Jul 17, 2023
6ff9226
missed one
FelixTJDietrich Jul 17, 2023
e61162b
Update module_example/module_example/__main__.py
FelixTJDietrich Jul 17, 2023
56f4e45
Update playground/src/components/module_response_view.tsx
FelixTJDietrich Jul 17, 2023
164a5f0
Update assessment_module_manager/assessment_module_manager/module/req…
FelixTJDietrich Jul 17, 2023
048f992
match example ordering
FelixTJDietrich Jul 17, 2023
582fd7b
whoops
FelixTJDietrich Jul 17, 2023
cfad94a
add error
FelixTJDietrich Jul 17, 2023
acb0d9d
change request_to_module
FelixTJDietrich Jul 17, 2023
e0f9e8b
add a warning
FelixTJDietrich Jul 17, 2023
bc41663
remove underscore
FelixTJDietrich Jul 17, 2023
fc22725
Update module_example/module_example/__main__.py
FelixTJDietrich Jul 17, 2023
baff4cd
change meta
FelixTJDietrich Jul 17, 2023
52507cb
Merge branch 'feature/llm-config' of https://github.com/ls1intum/athe…
FelixTJDietrich Jul 17, 2023
100832e
update package-lock
FelixTJDietrich Jul 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
from typing import Dict, Any
from typing import Dict, Any, Optional
from fastapi import Body, HTTPException, Request
from starlette.responses import JSONResponse

from assessment_module_manager.app import app
from assessment_module_manager.module import ModuleResponse, AvailableModuleNames, find_module_by_name, \
request_to_module
from athena.authenticate import authenticated
from athena.schemas import ExerciseType
from fastapi import HTTPException
from starlette.responses import JSONResponse
from assessment_module_manager.app import app
from assessment_module_manager.module import ModuleResponse, AvailableModuleNames, find_module_by_name, request_to_module


@app.post(
@app.api_route(
"/modules/{module_type}/{module_name}/{path:path}",
methods=["POST", "GET"],
responses={
400: {
"description": "Module is not of the requested type",
Expand All @@ -26,26 +26,33 @@
"description": "Module is not available",
},
},
response_model=ModuleResponse[Any],
response_model=ModuleResponse[Any, Any],
)
@authenticated
async def proxy_to_module(
module_type: ExerciseType, module_name: AvailableModuleNames, path: str, data: Dict[Any, Any],
module_type: ExerciseType, module_name: AvailableModuleNames, path: str, request: Request, data: Optional[Dict[Any, Any]] = Body(None),
) -> JSONResponse:
"""
This endpoint is called by the LMS to proxy requests to modules.
See the module documentation for the possible choices for paths.
Example module documentation on this: [http://localhost:5001/docs](http://localhost:5001/docs).
"""
if request.method == "GET" and data is not None:
raise HTTPException(status_code=400, detail="GET request should not contain a body")

module = await find_module_by_name(module_name)
if module is None:
raise HTTPException(status_code=404, detail=f"Module {module_name} not found. Is it listed in modules.ini?")
if module.type != module_type:
raise HTTPException(status_code=400, detail=f"Found module {module_name} is not of type {module_type}.")

module_config = request.headers.get('X-Module-Config')
resp = await request_to_module(
module,
module_config,
'/' + path,
data,
method=request.method,
)
return JSONResponse(
status_code=resp.status,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
from .available_module_enum import AvailableModuleNames
from .list_modules import list_modules
from assessment_module_manager import env
from assessment_module_manager.logger import logger

T = TypeVar('T')
class ModuleResponse(GenericModel, Generic[T]):
D = TypeVar('D')
M = TypeVar('M')
class ModuleResponse(GenericModel, Generic[D, M]):
"""
A response from a module.
"""
module_name: str
status: int
data: T
data: D
meta: M


async def find_module_by_name(
Expand All @@ -32,23 +35,36 @@ async def find_module_by_name(
return None


async def request_to_module(module: Module, path: str, data: dict) -> ModuleResponse:
async def request_to_module(module: Module, module_config: Optional[str], path: str, data: Optional[dict], method: str) -> ModuleResponse:
"""
Helper function to send a request to a module.
It raises appropriate FastAPI HTTPException if the request fails.
"""
module_secret = env.MODULE_SECRETS[module.name]
headers = {}
if module_secret:
headers['X-API-Secret'] = module_secret
if module_config:
headers['X-Module-Config'] = module_config

try:
async with httpx.AsyncClient(base_url=module.url, timeout=600) as client:
response = await client.post(path, json=data, headers={'X-API-Secret': module_secret} if module_secret else None)
if method == "POST":
response = await client.post(path, json=data, headers=headers)
elif method == "GET":
response = await client.get(path, headers=headers)
else:
raise NotImplementedError(f"Method {method} is not implemented")
except httpx.ConnectError as exc:
raise HTTPException(status_code=503, detail=f"Module {module.name} is not available") from exc

try:
response.raise_for_status()
except httpx.HTTPStatusError:
try:
response_data = response.json()
except json.JSONDecodeError:
response_data = response.text
return ModuleResponse(module_name=module.name, status=response.status_code, data=response_data)
return ModuleResponse(module_name=module.name, status=response.status_code, data=response.json())
response_data = response.json()
meta = response_data.get('meta', {})
response_data = response_data.get('data', response_data)
except json.JSONDecodeError:
response_data = response.text
FelixTJDietrich marked this conversation as resolved.
Show resolved Hide resolved
meta = None
logger.warning("Module %s returned non-JSON response: %s", module.name, response.text)

return ModuleResponse(module_name=module.name, status=response.status_code, data=response_data, meta=meta)
6 changes: 5 additions & 1 deletion athena/athena/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

from .app import app
from .schemas import ExerciseType
from .endpoints import submission_selector, submissions_consumer, feedback_consumer, feedback_provider # type: ignore
from .metadata import emit_meta, get_meta
from .endpoints import submission_selector, submissions_consumer, feedback_consumer, feedback_provider, config_schema_provider # type: ignore


@app.get("/")
Expand All @@ -25,6 +26,9 @@ def run_module():
"submissions_consumer",
"feedback_consumer",
"feedback_provider",
"config_schema_provider",
"emit_meta",
"get_meta",
"ExerciseType",
"app"
]
6 changes: 6 additions & 0 deletions athena/athena/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .database import create_tables
from .logger import logger
from .module_config import get_module_config
from .metadata import MetaDataMiddleware


class FastAPIWithStart(FastAPI):
Expand All @@ -18,6 +19,11 @@ class FastAPIWithStart(FastAPI):
We expose the start function this way to ensure that modules have to import `app`,
which uvicorn needs to discover in the module.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.add_middleware(MetaDataMiddleware)


def start(self) -> None:
"""Start Athena. You have to ensure to have `app` in your module main scope so that it can be imported."""
logger.info("Starting athena module")
Expand Down
Loading