winebox 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. winebox-0.1.0/.github/workflows/ci.yml +83 -0
  2. winebox-0.1.0/.github/workflows/publish.yml +74 -0
  3. winebox-0.1.0/.gitignore +62 -0
  4. winebox-0.1.0/.python-version +1 -0
  5. winebox-0.1.0/LICENSE +21 -0
  6. winebox-0.1.0/PKG-INFO +283 -0
  7. winebox-0.1.0/README.md +237 -0
  8. winebox-0.1.0/docs/api-reference.md +358 -0
  9. winebox-0.1.0/docs/conf.py +51 -0
  10. winebox-0.1.0/docs/index.md +169 -0
  11. winebox-0.1.0/docs/user-guide.md +174 -0
  12. winebox-0.1.0/pyproject.toml +70 -0
  13. winebox-0.1.0/tasks.py +223 -0
  14. winebox-0.1.0/tests/__init__.py +1 -0
  15. winebox-0.1.0/tests/conftest.py +146 -0
  16. winebox-0.1.0/tests/test_ocr.py +161 -0
  17. winebox-0.1.0/tests/test_search.py +158 -0
  18. winebox-0.1.0/tests/test_transactions.py +93 -0
  19. winebox-0.1.0/tests/test_wines.py +212 -0
  20. winebox-0.1.0/uv.lock +1589 -0
  21. winebox-0.1.0/winebox/__init__.py +3 -0
  22. winebox-0.1.0/winebox/cli/__init__.py +1 -0
  23. winebox-0.1.0/winebox/cli/server.py +313 -0
  24. winebox-0.1.0/winebox/cli/user_admin.py +258 -0
  25. winebox-0.1.0/winebox/config.py +43 -0
  26. winebox-0.1.0/winebox/database.py +47 -0
  27. winebox-0.1.0/winebox/main.py +78 -0
  28. winebox-0.1.0/winebox/models/__init__.py +8 -0
  29. winebox-0.1.0/winebox/models/inventory.py +46 -0
  30. winebox-0.1.0/winebox/models/transaction.py +64 -0
  31. winebox-0.1.0/winebox/models/user.py +55 -0
  32. winebox-0.1.0/winebox/models/wine.py +66 -0
  33. winebox-0.1.0/winebox/routers/__init__.py +5 -0
  34. winebox-0.1.0/winebox/routers/auth.py +90 -0
  35. winebox-0.1.0/winebox/routers/cellar.py +102 -0
  36. winebox-0.1.0/winebox/routers/search.py +127 -0
  37. winebox-0.1.0/winebox/routers/transactions.py +63 -0
  38. winebox-0.1.0/winebox/routers/wines.py +287 -0
  39. winebox-0.1.0/winebox/schemas/__init__.py +13 -0
  40. winebox-0.1.0/winebox/schemas/transaction.py +40 -0
  41. winebox-0.1.0/winebox/schemas/wine.py +79 -0
  42. winebox-0.1.0/winebox/services/__init__.py +7 -0
  43. winebox-0.1.0/winebox/services/auth.py +123 -0
  44. winebox-0.1.0/winebox/services/image_storage.py +90 -0
  45. winebox-0.1.0/winebox/services/ocr.py +128 -0
  46. winebox-0.1.0/winebox/services/wine_parser.py +411 -0
  47. winebox-0.1.0/winebox/static/css/style.css +1086 -0
  48. winebox-0.1.0/winebox/static/index.html +271 -0
  49. winebox-0.1.0/winebox/static/js/app.js +703 -0
@@ -0,0 +1,83 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ name: Test Python ${{ matrix.python-version }}
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ python-version: ["3.11", "3.12"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install Tesseract OCR
27
+ run: sudo apt-get update && sudo apt-get install -y tesseract-ocr
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v4
31
+
32
+ - name: Install dependencies
33
+ run: uv sync --all-extras
34
+
35
+ - name: Run tests
36
+ run: uv run pytest -v
37
+
38
+ lint:
39
+ name: Lint
40
+ runs-on: ubuntu-latest
41
+
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+
45
+ - name: Set up Python
46
+ uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.11"
49
+
50
+ - name: Install uv
51
+ uses: astral-sh/setup-uv@v4
52
+
53
+ - name: Install dependencies
54
+ run: uv sync --all-extras
55
+
56
+ - name: Check import sorting with isort
57
+ run: uv run pip install isort && uv run isort --check-only --diff winebox tests
58
+ continue-on-error: true
59
+
60
+ build:
61
+ name: Build package
62
+ runs-on: ubuntu-latest
63
+
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+
67
+ - name: Set up Python
68
+ uses: actions/setup-python@v5
69
+ with:
70
+ python-version: "3.11"
71
+
72
+ - name: Install build dependencies
73
+ run: |
74
+ python -m pip install --upgrade pip
75
+ pip install build
76
+
77
+ - name: Build package
78
+ run: python -m build
79
+
80
+ - name: Check package
81
+ run: |
82
+ pip install twine
83
+ twine check dist/*
@@ -0,0 +1,74 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build distribution
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.11"
19
+
20
+ - name: Install build dependencies
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ pip install build
24
+
25
+ - name: Build package
26
+ run: python -m build
27
+
28
+ - name: Store distribution packages
29
+ uses: actions/upload-artifact@v4
30
+ with:
31
+ name: python-package-distributions
32
+ path: dist/
33
+
34
+ publish-to-pypi:
35
+ name: Publish to PyPI
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ environment:
39
+ name: pypi
40
+ url: https://pypi.org/p/winebox
41
+ permissions:
42
+ id-token: write # Required for trusted publishing
43
+
44
+ steps:
45
+ - name: Download distributions
46
+ uses: actions/download-artifact@v4
47
+ with:
48
+ name: python-package-distributions
49
+ path: dist/
50
+
51
+ - name: Publish to PyPI
52
+ uses: pypa/gh-action-pypi-publish@release/v1
53
+
54
+ publish-to-testpypi:
55
+ name: Publish to TestPyPI
56
+ needs: build
57
+ runs-on: ubuntu-latest
58
+ environment:
59
+ name: testpypi
60
+ url: https://test.pypi.org/p/winebox
61
+ permissions:
62
+ id-token: write # Required for trusted publishing
63
+
64
+ steps:
65
+ - name: Download distributions
66
+ uses: actions/download-artifact@v4
67
+ with:
68
+ name: python-package-distributions
69
+ path: dist/
70
+
71
+ - name: Publish to TestPyPI
72
+ uses: pypa/gh-action-pypi-publish@release/v1
73
+ with:
74
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,62 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+ *~
34
+
35
+ # Testing
36
+ .pytest_cache/
37
+ .coverage
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+
42
+ # Data (local database and images)
43
+ data/
44
+ *.db
45
+
46
+ # Environment variables
47
+ .env
48
+ .env.local
49
+
50
+ # OS files
51
+ .DS_Store
52
+ Thumbs.db
53
+
54
+ # Sphinx documentation
55
+ docs/_build/
56
+
57
+ # Logs
58
+ *.log
59
+
60
+ # Temporary files
61
+ tmp/
62
+ temp/
@@ -0,0 +1 @@
1
+ 3.11
winebox-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Joe Drumgoole
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.
winebox-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,283 @@
1
+ Metadata-Version: 2.4
2
+ Name: winebox
3
+ Version: 0.1.0
4
+ Summary: Wine Cellar Management Application with OCR label scanning
5
+ Project-URL: Homepage, https://github.com/jdrumgoole/winebox
6
+ Project-URL: Repository, https://github.com/jdrumgoole/winebox
7
+ Project-URL: Issues, https://github.com/jdrumgoole/winebox/issues
8
+ Author-email: Joe Drumgoole <joe@joedrumgoole.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: cellar,fastapi,inventory,ocr,wine
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Home Automation
22
+ Requires-Python: >=3.11
23
+ Requires-Dist: aiofiles>=23.0.0
24
+ Requires-Dist: aiosqlite>=0.19.0
25
+ Requires-Dist: bcrypt<4.1.0,>=4.0.0
26
+ Requires-Dist: fastapi>=0.109.0
27
+ Requires-Dist: jinja2>=3.1.0
28
+ Requires-Dist: passlib>=1.7.4
29
+ Requires-Dist: pillow>=10.0.0
30
+ Requires-Dist: pydantic-settings>=2.0.0
31
+ Requires-Dist: pydantic>=2.0.0
32
+ Requires-Dist: pytesseract>=0.3.10
33
+ Requires-Dist: python-jose[cryptography]>=3.3.0
34
+ Requires-Dist: python-multipart>=0.0.6
35
+ Requires-Dist: sqlalchemy>=2.0.0
36
+ Requires-Dist: uvicorn[standard]>=0.27.0
37
+ Provides-Extra: dev
38
+ Requires-Dist: greenlet>=3.0.0; extra == 'dev'
39
+ Requires-Dist: httpx>=0.26.0; extra == 'dev'
40
+ Requires-Dist: invoke>=2.2.0; extra == 'dev'
41
+ Requires-Dist: myst-parser>=2.0.0; extra == 'dev'
42
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
43
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
44
+ Requires-Dist: sphinx>=7.0.0; extra == 'dev'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # WineBox
48
+
49
+ A wine cellar management application with OCR label scanning.
50
+
51
+ ## Features
52
+
53
+ - **Label Scanning**: Upload wine label images for automatic text extraction via OCR
54
+ - **Inventory Tracking**: Check-in and check-out bottles with full history
55
+ - **Smart Parsing**: Automatically identifies vintage, grape variety, region, and more
56
+ - **Search**: Find wines by any criteria
57
+ - **Web Interface**: Simple, mobile-friendly interface
58
+
59
+ ## Quick Start
60
+
61
+ ### Prerequisites
62
+
63
+ - Python 3.11+
64
+ - [Tesseract OCR](https://github.com/tesseract-ocr/tesseract)
65
+
66
+ ### Installation
67
+
68
+ **From PyPI:**
69
+ ```bash
70
+ pip install winebox
71
+ ```
72
+
73
+ **From source:**
74
+ ```bash
75
+ # Clone the repository
76
+ git clone https://github.com/jdrumgoole/winebox.git
77
+ cd winebox
78
+
79
+ # Install dependencies
80
+ uv sync --all-extras
81
+
82
+ # Install Tesseract OCR
83
+ # macOS:
84
+ brew install tesseract
85
+
86
+ # Ubuntu/Debian:
87
+ sudo apt-get install tesseract-ocr
88
+ ```
89
+
90
+ ### Running the Server
91
+
92
+ ```bash
93
+ # Development mode with auto-reload
94
+ invoke start --reload
95
+
96
+ # Background mode
97
+ invoke start-background
98
+
99
+ # Check status
100
+ invoke status
101
+
102
+ # Stop server
103
+ invoke stop
104
+ ```
105
+
106
+ ### Access the Application
107
+
108
+ - **Web Interface**: http://localhost:8000/static/index.html
109
+ - **API Documentation**: http://localhost:8000/docs
110
+ - **Health Check**: http://localhost:8000/health
111
+
112
+ ## Usage
113
+
114
+ ### Check In Wine
115
+
116
+ 1. Navigate to the Check In page
117
+ 2. Upload front label image (required)
118
+ 3. Optionally upload back label image
119
+ 4. Review/edit auto-detected wine details
120
+ 5. Set quantity and add notes
121
+ 6. Click "Check In Wine"
122
+
123
+ ### Check Out Wine
124
+
125
+ 1. Go to the Cellar view
126
+ 2. Click "Check Out" on a wine card
127
+ 3. Enter quantity to remove
128
+ 4. Add optional notes (tasting notes, occasion)
129
+ 5. Confirm checkout
130
+
131
+ ### Search
132
+
133
+ Use the Search page to find wines by:
134
+ - Text search (name, winery, region)
135
+ - Vintage year
136
+ - Grape variety
137
+ - Region or country
138
+ - Stock status
139
+
140
+ ## API
141
+
142
+ Full REST API available at `/api`:
143
+
144
+ | Endpoint | Method | Description |
145
+ |----------|--------|-------------|
146
+ | `/api/wines/checkin` | POST | Add wine to cellar |
147
+ | `/api/wines/{id}/checkout` | POST | Remove wine from cellar |
148
+ | `/api/wines` | GET | List all wines |
149
+ | `/api/wines/{id}` | GET | Get wine details |
150
+ | `/api/cellar` | GET | Current inventory |
151
+ | `/api/cellar/summary` | GET | Cellar statistics |
152
+ | `/api/transactions` | GET | Transaction history |
153
+ | `/api/search` | GET | Search wines |
154
+
155
+ See `/docs` for interactive API documentation.
156
+
157
+ ## Data Storage
158
+
159
+ ### Database
160
+
161
+ The SQLite database is stored at `data/winebox.db` by default. This can be configured via the `WINEBOX_DATABASE_URL` environment variable.
162
+
163
+ ### Images
164
+
165
+ Wine label images are stored in the `data/images/` directory by default. Each image is saved with a UUID filename to avoid conflicts.
166
+
167
+ | Item | Default Location | Environment Variable |
168
+ |------|------------------|---------------------|
169
+ | Database | `data/winebox.db` | `WINEBOX_DATABASE_URL` |
170
+ | Images | `data/images/` | `WINEBOX_IMAGE_STORAGE_PATH` |
171
+
172
+ Images are served via the API at `/api/images/{filename}`.
173
+
174
+ **Note:** The `data/` directory is excluded from git (see `.gitignore`). Make sure to back up this directory to preserve your wine collection data.
175
+
176
+ ## Authentication
177
+
178
+ WineBox requires authentication for all API endpoints (except `/health`).
179
+
180
+ ### Creating Users
181
+
182
+ Use the `winebox-admin` command to manage users:
183
+
184
+ ```bash
185
+ # Create an admin user
186
+ uv run winebox-admin add admin --email admin@example.com --admin --password yourpassword
187
+
188
+ # Create a regular user
189
+ uv run winebox-admin add username --email user@example.com --password yourpassword
190
+
191
+ # List all users
192
+ uv run winebox-admin list
193
+
194
+ # Disable/enable a user
195
+ uv run winebox-admin disable username
196
+ uv run winebox-admin enable username
197
+
198
+ # Change password
199
+ uv run winebox-admin passwd username --password newpassword
200
+
201
+ # Remove a user
202
+ uv run winebox-admin remove username
203
+ ```
204
+
205
+ ### Server Management
206
+
207
+ Use the `winebox-server` command to manage the server:
208
+
209
+ ```bash
210
+ # Start server (foreground)
211
+ uv run winebox-server start --foreground
212
+
213
+ # Start server (background)
214
+ uv run winebox-server start
215
+
216
+ # Stop server
217
+ uv run winebox-server stop
218
+
219
+ # Restart server
220
+ uv run winebox-server restart
221
+
222
+ # Check status
223
+ uv run winebox-server status
224
+ ```
225
+
226
+ ### API Authentication
227
+
228
+ The API uses JWT bearer tokens. To authenticate:
229
+
230
+ 1. POST to `/api/auth/token` with `username` and `password` (form-urlencoded)
231
+ 2. Include the returned token in subsequent requests: `Authorization: Bearer <token>`
232
+
233
+ Tokens expire after 24 hours.
234
+
235
+ ## Development
236
+
237
+ ### Running Tests
238
+
239
+ ```bash
240
+ # Run all tests
241
+ invoke test
242
+
243
+ # With verbose output
244
+ invoke test --verbose
245
+
246
+ # With coverage
247
+ invoke test --coverage
248
+ ```
249
+
250
+ ### Project Structure
251
+
252
+ ```
253
+ winebox/
254
+ ├── winebox/ # Application package
255
+ │ ├── main.py # FastAPI app
256
+ │ ├── models/ # Database models
257
+ │ ├── schemas/ # API schemas
258
+ │ ├── routers/ # API endpoints
259
+ │ ├── services/ # Business logic
260
+ │ └── static/ # Web interface
261
+ ├── tests/ # Test suite
262
+ ├── docs/ # Documentation
263
+ └── tasks.py # Build tasks
264
+ ```
265
+
266
+ ### Building Documentation
267
+
268
+ ```bash
269
+ invoke docs-build
270
+ invoke docs-serve
271
+ ```
272
+
273
+ ## Tech Stack
274
+
275
+ - **FastAPI**: Web framework
276
+ - **SQLAlchemy**: ORM
277
+ - **SQLite**: Database
278
+ - **Tesseract**: OCR engine
279
+ - **Vanilla JS**: Frontend (no frameworks)
280
+
281
+ ## License
282
+
283
+ MIT License