This is an automated email from the ASF dual-hosted git repository. xiaozhenliu pushed a commit to branch feat/xiaozhen-chat-assistant-1-backend-skeleton in repository https://gitbox.apache.org/repos/asf/texera.git
commit 96d1b5a29bcf30494e3d516aec6ffac445583872 Author: Xiaozhen Liu <[email protected]> AuthorDate: Wed Oct 15 16:20:12 2025 -0700 feat: [chat-assistant-service][1] add backend service skeleton --- .github/workflows/github-action-build.yml | 24 +++ chat-assistant-service/.gitignore | 181 +++++++++++++++++++++ chat-assistant-service/app/__init__.py | 16 ++ chat-assistant-service/app/create_app.py | 37 +++++ chat-assistant-service/app/tests/__init__.py | 16 ++ .../app/tests/test_health_check.py | 41 +++++ chat-assistant-service/main.py | 33 ++++ chat-assistant-service/pyproject.toml | 23 +++ chat-assistant-service/requirements.txt | 74 +++++++++ 9 files changed, 445 insertions(+) diff --git a/.github/workflows/github-action-build.yml b/.github/workflows/github-action-build.yml index e5f95ff235..9e6b1d7e62 100644 --- a/.github/workflows/github-action-build.yml +++ b/.github/workflows/github-action-build.yml @@ -155,3 +155,27 @@ jobs: - name: Test with pytest run: | cd amber/src/main/python && pytest -sv --ignore=core/models/test_RTableExecutor.py + + chat_assistant_service: + strategy: + matrix: + os: [ ubuntu-latest ] + python-version: [ '3.12' ] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Texera + uses: actions/checkout@v5 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r chat-assistant-service/requirements.txt + - name: Lint with flake8 and black + run: | + cd chat-assistant-service && flake8 && black . --check + - name: Test with pytest + run: | + cd chat-assistant-service && pytest -sv diff --git a/chat-assistant-service/.gitignore b/chat-assistant-service/.gitignore new file mode 100644 index 0000000000..aeb7b03537 --- /dev/null +++ b/chat-assistant-service/.gitignore @@ -0,0 +1,181 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + diff --git a/chat-assistant-service/app/__init__.py b/chat-assistant-service/app/__init__.py new file mode 100644 index 0000000000..13a83393a9 --- /dev/null +++ b/chat-assistant-service/app/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/chat-assistant-service/app/create_app.py b/chat-assistant-service/app/create_app.py new file mode 100644 index 0000000000..765b5f146c --- /dev/null +++ b/chat-assistant-service/app/create_app.py @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +""" +FastAPI application factory for the Chat Assistant Service. +""" +from fastapi import FastAPI + + +def create_app() -> FastAPI: + """ + Create the ChatAssistantService application. + """ + + app = FastAPI() + + @app.get("/api/healthcheck", tags=["Health"]) + async def healthcheck(): + """Health check endpoint for K8s liveness/readiness probes.""" + return {"status": "ok"} + + return app diff --git a/chat-assistant-service/app/tests/__init__.py b/chat-assistant-service/app/tests/__init__.py new file mode 100644 index 0000000000..13a83393a9 --- /dev/null +++ b/chat-assistant-service/app/tests/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/chat-assistant-service/app/tests/test_health_check.py b/chat-assistant-service/app/tests/test_health_check.py new file mode 100644 index 0000000000..8b9d0f5a07 --- /dev/null +++ b/chat-assistant-service/app/tests/test_health_check.py @@ -0,0 +1,41 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Test health check endpoint.""" +import pytest +from fastapi.testclient import TestClient +from app.create_app import create_app + + [email protected] +def client(): + """Create test client.""" + app = create_app() + return TestClient(app) + + +def test_app_creation(): + """Test that the app can be created successfully.""" + app = create_app() + assert app is not None + + +def test_health_check(client): + """Test health check endpoint returns correct response.""" + response = client.get("/api/healthcheck") + assert response.status_code == 200 + assert response.json() == {"status": "ok"} diff --git a/chat-assistant-service/main.py b/chat-assistant-service/main.py new file mode 100644 index 0000000000..4f79bc8455 --- /dev/null +++ b/chat-assistant-service/main.py @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Entry point for the Chat Assistant Service. + +Starts the FastAPI application with Uvicorn on port 8001. +""" +import logging +import uvicorn +from app.create_app import create_app + +logging.basicConfig(level=logging.INFO) +app = create_app() + +if __name__ == "__main__": + # Run with auto-reload for development + # Host 0.0.0.0 allows external connections (needed for Docker) + uvicorn.run("main:app", host="0.0.0.0", port=8001, reload=True) diff --git a/chat-assistant-service/pyproject.toml b/chat-assistant-service/pyproject.toml new file mode 100644 index 0000000000..7e03cef8cf --- /dev/null +++ b/chat-assistant-service/pyproject.toml @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[tool.black] +line-length = 88 +target-version = ["py312"] + +[tool.flake8] +max-line-length = 88 diff --git a/chat-assistant-service/requirements.txt b/chat-assistant-service/requirements.txt new file mode 100644 index 0000000000..37e8f74e78 --- /dev/null +++ b/chat-assistant-service/requirements.txt @@ -0,0 +1,74 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +annotated-types==0.7.0 +anyio==4.9.0 +attrs==25.4.0 +black==25.1.0 +certifi==2025.1.31 +charset-normalizer==3.4.1 +click==8.1.8 +colorama==0.4.6 +distro==1.9.0 +fastapi==0.115.12 +flake8==7.2.0 +Flake8-pyproject==1.2.3 +graphviz==0.20.3 +griffe==1.7.2 +h11==0.14.0 +httpcore==1.0.7 +httptools==0.6.4 +httpx==0.28.1 +httpx-sse==0.4.0 +idna==3.10 +jiter==0.9.0 +jsonschema==4.25.1 +jsonschema-specifications==2025.9.1 +mccabe==0.7.0 +mcp==1.16.0 +mypy_extensions==1.1.0 +openai==1.109.1 +openai-agents==0.3.3 +packaging==25.0 +pathspec==0.12.1 +platformdirs==4.3.8 +pycodestyle==2.13.0 +pydantic==2.11.4 +pydantic-settings==2.8.1 +pydantic_core==2.33.2 +pyflakes==3.3.2 +python-dotenv==1.1.0 +python-multipart==0.0.20 +PyYAML==6.0.2 +referencing==0.36.2 +requests==2.32.3 +rpds-py==0.27.1 +setuptools==78.1.1 +sniffio==1.3.1 +sse-starlette==2.2.1 +starlette==0.47.2 +tqdm==4.67.1 +types-requests==2.32.0.20250328 +typing-inspection==0.4.0 +typing_extensions==4.13.2 +urllib3==2.5.0 +uvicorn==0.34.0 +uvloop==0.21.0 +watchfiles==1.0.5 +websockets==15.0.1 +wheel==0.45.1 +pytest~=8.4.2 \ No newline at end of file
