Project-tester-01 commited on
Commit
62ed149
·
verified ·
1 Parent(s): 8aa9ed6

Upload folder using huggingface_hub

Browse files
Files changed (7) hide show
  1. .github/workflows/sync.yml +33 -0
  2. .gitignore +218 -0
  3. Dockerfile +14 -2
  4. LICENSE +21 -0
  5. README.md +6 -14
  6. app.py +133 -0
  7. requirements.txt +3 -3
.github/workflows/sync.yml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync to Hugging Face Hub
2
+
3
+ on:
4
+ push:
5
+ branches: ["main","staging"]
6
+ # Allows you to manually trigger this workflow from the Actions tab
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ deploy:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository assets
14
+ uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+
18
+ - name: Set up Python environment
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: '3.10'
22
+
23
+ - name: Install official Hugging Face CLI tool
24
+ run: pip install huggingface_hub
25
+
26
+ - name: Authenticate and upload project space via dedicated tunnel
27
+ env:
28
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
29
+ # Traffic Controller: If the branch is main, use production. Otherwise, use staging.
30
+ HF_SPACE: ${{ github.ref_name == 'main' && 'catalyst-intelligence/ClariFood' || 'catalyst-intelligence/Staging-ClariFood' }}
31
+ run: |
32
+ hf auth login --token $HF_TOKEN
33
+ hf upload $HF_SPACE . --repo-type space
.gitignore ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
Dockerfile CHANGED
@@ -1,20 +1,32 @@
 
1
  FROM python:3.13.5-slim
2
 
 
3
  WORKDIR /app
4
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
8
  git \
 
 
9
  && rm -rf /var/lib/apt/lists/*
10
 
 
11
  COPY requirements.txt ./
12
- COPY src/ ./src/
13
 
 
14
  RUN pip3 install -r requirements.txt
15
 
 
 
 
 
16
  EXPOSE 8501
17
 
 
18
  HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
19
 
20
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
 
1
+ # Using the official lightweight Python image as a foundation
2
  FROM python:3.13.5-slim
3
 
4
+ # Setup the operational directory inside the virtual container
5
  WORKDIR /app
6
 
7
+ # Linux system configuration sequence
8
  RUN apt-get update && apt-get install -y \
9
  build-essential \
10
  curl \
11
  git \
12
+ libzbar0 \
13
+ libgl1-mesa-glx \
14
  && rm -rf /var/lib/apt/lists/*
15
 
16
+ # Copy requirements map
17
  COPY requirements.txt ./
 
18
 
19
+ # install dependancies
20
  RUN pip3 install -r requirements.txt
21
 
22
+ # Copy main application file directly from your root folder
23
+ COPY app.py ./
24
+
25
+ # Tell container to open the port the app listens to
26
  EXPOSE 8501
27
 
28
+ # Health monitoring
29
  HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
30
 
31
+ # Boot execution
32
+ ENTRYPOINT ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Catalyst Intelligence
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,19 +1,11 @@
1
  ---
2
- title: Staging ClariFood
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: red
6
  sdk: docker
7
  app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Beta testing of ClariFood webpage is done here.
12
  ---
13
 
14
- # Welcome to Streamlit!
15
-
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
-
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
1
  ---
2
+ title: ClariFood
3
+ emoji: 🥑
4
+ colorFrom: green
5
+ colorTo: yellow # "colorTo" must be one of [red, yellow, green, blue, indigo, purple, pink, gray]
6
  sdk: docker
7
  app_port: 8501
 
 
 
 
8
  ---
9
 
10
+ # 🥑 ClariFood
11
+ Conversational diet intelligence platform powered by LLM. Developed under the Catalyst Intelligence collective with the help of AI.
 
 
 
 
app.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import cv2
3
+ import numpy as np
4
+ from google import genai
5
+ from PIL import Image
6
+
7
+ # Initialize Gemini Client
8
+ client = genai.Client()
9
+
10
+ # Force full viewport usage to widen the camera layout frame
11
+ st.set_page_config(page_title="ClariFood", page_icon="🛡️", layout="wide")
12
+
13
+ st.title("🛡️ ClariFood: Conversational Diet Intelligence")
14
+ st.write("A production-hardened hybrid edge/cloud system with dynamic session memory.")
15
+
16
+ st.markdown("---")
17
+
18
+ # --- STEP 1: CONTEXT INJECTION DECK (SIDEBAR) ---
19
+ st.sidebar.header("👤 Dynamic Health Profile")
20
+
21
+ goal_options = ["Weight Loss", "Muscle Gain / Clean Bulk", "Diabetes Management", "Hypertension Control", "Gluten-Free Induction"]
22
+ selected_goals = st.sidebar.multiselect("Primary Objectives", options=goal_options)
23
+
24
+ # Custom Goal Input Gate
25
+ custom_goal_active = st.sidebar.checkbox("Inject custom targets?")
26
+ custom_goal_text = ""
27
+ if custom_goal_active:
28
+ custom_goal_text = st.sidebar.text_input("Type custom health profile constraints:")
29
+
30
+ allergy_options = ["Dairy", "Nuts", "Gluten", "Soy", "Artificial Sweeteners", "Preservatives"]
31
+ selected_allergies = st.sidebar.multiselect("STRICT Avoidances / Allergies", options=allergy_options)
32
+
33
+ additional_notes = st.sidebar.text_area("Narrative Clinical Notes (e.g., medical conditions):")
34
+
35
+ # Construct the master string block
36
+ final_goals = selected_goals + ([custom_goal_text] if custom_goal_text else [])
37
+ user_profile_context = f"""
38
+ USER HEALTH PROFILE DOSSIER:
39
+ - Objectives: {', '.join(final_goals) if final_goals else 'General Fitness Check'}
40
+ - Strict Allergens to Flag: {', '.join(selected_allergies) if selected_allergies else 'None specified'}
41
+ - Medical/Narrative Notes: {additional_notes if additional_notes else 'None provided'}
42
+ """
43
+
44
+ # --- STEP 2: CONVERSATIONAL MEMORY INITIALIZATION ---
45
+ if "chat_history" not in st.session_state:
46
+ st.session_state.chat_history = []
47
+ if "vault_images" not in st.session_state:
48
+ st.session_state.vault_images = []
49
+
50
+ # --- STEP 3: MULTI-IMAGE ACQUISITION CANVAS ---
51
+ st.subheader("📸 Frame Capture Pipeline")
52
+ col_cam, col_vault = st.columns([2, 3])
53
+
54
+ with col_cam:
55
+ captured_file = st.camera_input("Position product packaging in center view")
56
+ if captured_file is not None:
57
+ img = Image.open(captured_file)
58
+
59
+ # Guard against duplicates inside the active frame cycle
60
+ if len(st.session_state.vault_images) == 0 or captured_file.name != st.session_state.get("last_uploaded_name", ""):
61
+ st.session_state.vault_images.append(img)
62
+ st.session_state.last_uploaded_name = captured_file.name
63
+ st.success(f"Frame buffered into system memory! Canvas Count: {len(st.session_state.vault_images)}")
64
+
65
+ with col_vault:
66
+ if st.session_state.vault_images:
67
+ st.write("⚡ **Buffered Frame Stack Active:**")
68
+ # Render thumbnails of all taken photos side-by-side
69
+ thumb_cols = st.columns(min(len(st.session_state.vault_images), 4))
70
+ for idx, thumb_img in enumerate(st.session_state.vault_images):
71
+ with thumb_cols[idx % 4]:
72
+ st.image(thumb_img, caption=f"Scan #{idx+1}", width=120)
73
+
74
+ if st.button("🗑️ Clear Image Stack"):
75
+ st.session_state.vault_images = []
76
+ st.rerun()
77
+
78
+ st.markdown("---")
79
+
80
+ # --- STEP 4: INTERACTIVE CHAT ENGINE LAYOUT ---
81
+ st.subheader("💬 AI Clinical Consultation Stream")
82
+
83
+ # Render previous conversational statements
84
+ for message in st.session_state.chat_history:
85
+ with st.chat_message(message["role"]):
86
+ st.markdown(message["content"])
87
+
88
+ # System Execution Prompter
89
+ if user_message := st.chat_input("Ask a question about your scanned items..."):
90
+
91
+ # 1. Display User Message Instantly
92
+ st.session_state.chat_history.append({"role": "user", "content": user_message})
93
+ with st.chat_message("user"):
94
+ st.markdown(user_message)
95
+
96
+ # 2. Build Multi-modal Prompt Strategy
97
+ # Construct systemic ground truth logic framework
98
+ system_logic_prompt = f"""
99
+ You are an expert digital dietitian. You are analyzing an interactive product scan loop.
100
+
101
+ CRITICAL OPERATION PROTOCOLS:
102
+ 1. Cross-reference all inputs against this profile context: {user_profile_context}
103
+ 2. Analyze the attached sequence of product photos sequentially.
104
+ 3. If the user's query requires finer granular data that you cannot see in the current image stack, or if a photo is unclear, DO NOT guess. State your initial observation and explicitly request the user to take an additional focused scan.
105
+
106
+ CURRENT CHAT HISTORY DIALOGUE FOR TRACKING CONTEXT:
107
+ """
108
+
109
+ # Pack background context strings, active image arrays, and current input together
110
+ payload = [system_logic_prompt]
111
+
112
+ # Compile chat history text strings into payload
113
+ for msg in st.session_state.chat_history[:-1]:
114
+ payload.append(f"{msg['role'].upper()}: {msg['content']}\n")
115
+
116
+ # Inject our list of images directly into the multimodal generation array
117
+ payload.extend(st.session_state.vault_images)
118
+
119
+ # Inject current fresh query prompt
120
+ payload.append(f"CURRENT USER INQUIRY: {user_message}\nASSISTANT SYSTEM OUTPUT:")
121
+
122
+ # 3. Call Cloud Model Infrastructure
123
+ with st.chat_message("assistant"):
124
+ with st.spinner("Analyzing data streams..."):
125
+ try:
126
+ response = client.models.generate_content(
127
+ model='gemini-2.5-flash',
128
+ contents=payload
129
+ )
130
+ st.markdown(response.text)
131
+ st.session_state.chat_history.append({"role": "assistant", "content": response.text})
132
+ except Exception as e:
133
+ st.error(f"Execution Error: {e}")
requirements.txt CHANGED
@@ -1,3 +1,3 @@
1
- altair
2
- pandas
3
- streamlit
 
1
+ google-genai
2
+ streamlit
3
+ opencv-python-headless