Skip to content

Commit 4778ced

Browse files
committed
Initial commit with db and tests
1 parent 6da01ff commit 4778ced

8 files changed

Lines changed: 5195 additions & 0 deletions

File tree

.gitignore

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
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+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# PyInstaller
28+
# Usually these files are written by a python script from a template
29+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.nox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*.cover
47+
*.py,cover
48+
.hypothesis/
49+
.pytest_cache/
50+
51+
# Translations
52+
*.mo
53+
*.pot
54+
55+
# Django stuff:
56+
*.log
57+
local_settings.py
58+
db.sqlite3
59+
db.sqlite3-journal
60+
61+
# Flask stuff:
62+
instance/
63+
.webassets-cache
64+
65+
# Scrapy stuff:
66+
.scrapy
67+
68+
# Sphinx documentation
69+
docs/_build/
70+
71+
# PyBuilder
72+
target/
73+
74+
# Jupyter Notebook
75+
.ipynb_checkpoints
76+
77+
# IPython
78+
profile_default/
79+
ipython
80+
81+
.egg-info

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"."
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true
7+
}

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@ They've suggested a public dataset from Kaggle to seed your product catalogue:
6060
- You do **not need to deploy** the application — running locally is perfectly fine.
6161
- **Code quality is important** to StyleDen.
6262
Your solution should be **well-designed** and **written in a test-driven manner**.
63+
64+
65+
---
66+
67+
## Design Doc from ChatGPT
68+
69+
https://chatgpt.com/share/680cb4dd-78b0-8000-9039-0861c2b0e24c
70+
71+
## Local Setup steps
72+
73+
`pip install -e .[dev]`

data/styles.csv

Lines changed: 4999 additions & 0 deletions
Large diffs are not rendered by default.

fashion_items.db

500 KB
Binary file not shown.

pyproject.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[build-system]
2+
requires = ["setuptools", "setuptools-scm"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "styleden_api"
7+
version = "0"
8+
9+
dependencies = ["fastapi", "uvicorn[standard]", "pandas"]
10+
11+
[project.optional-dependencies]
12+
dev = ["pytest", "pytest-mock", "pytest-asyncio", "pytest-httpx", "ruff"]
13+
[tool.pytest.ini_options]
14+
addopts = ["--import-mode=importlib"]
15+
16+
[tool.ruff]
17+
# Assume Python 3.11
18+
target-version = "py311"
19+
# Set src directory for import order
20+
src = ["src"]
21+
22+
[tool.ruff.lint]
23+
# Enable pycodestyle (`E`) & (`W`), Pyflakes (`F`), flake8-bandit (`S`), flake8-bugbear (`B`), flake8-annotations (`ANN`) and isort (`I`)
24+
select = ["E", "W", "F", "S", "B", "ANN", "I"]
25+
ignore = [
26+
"ANN101", # Deprecated rule
27+
"ANN204", # Ignore return types on "special" methods, like __init__, __new__, and __call__
28+
]
29+
30+
[tool.ruff.lint.per-file-ignores]
31+
"tests/*.py" = [
32+
"S101", # asserts are allowed in tests
33+
"ANN201", # No type return needed in tests
34+
"ANN001", # No input type needed in tests
35+
]

src/db_import.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import sqlite3
2+
3+
import pandas as pd
4+
5+
6+
def seed_database(csv_file="data/styles.csv", db_file="fashion_items.db"):
7+
# Load the CSV data into a pandas DataFrame
8+
df = pd.read_csv(csv_file)
9+
10+
# Create a SQLite database connection
11+
conn = sqlite3.connect(db_file)
12+
13+
# Write the DataFrame to a SQLite table
14+
table_name = "fashion_items"
15+
df.to_sql(table_name, conn, if_exists="replace", index=False)
16+
17+
# Close the database connection
18+
conn.close()
19+
20+
print(
21+
f"Data from {csv_file} has been successfully loaded into the SQLite database '{db_file}' in the table '{table_name}'."
22+
)
23+
24+
25+
# Run the seed script if executed directly
26+
if __name__ == "__main__":
27+
seed_database()

tests/test_db_seed.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
import sqlite3
3+
4+
import db_import
5+
import pandas as pd
6+
7+
8+
# Test for the database seed script
9+
def test_db_seed():
10+
# Ensure the database file does not exist before the test
11+
db_file = 'test_fashion_items.db'
12+
if os.path.exists(db_file):
13+
os.remove(db_file)
14+
15+
# Run the seed script with the test database file
16+
db_import.seed_database(db_file=db_file)
17+
18+
# Verify the database file was created
19+
assert os.path.exists(db_file), "Database file was not created."
20+
21+
# Verify the table and data
22+
conn = sqlite3.connect(db_file)
23+
cursor = conn.cursor()
24+
25+
# Check if the table exists
26+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='fashion_items';")
27+
assert cursor.fetchone() is not None, "Table 'fashion_items' was not created."
28+
29+
# Check if data was inserted
30+
df = pd.read_sql_query("SELECT * FROM fashion_items;", conn)
31+
assert not df.empty, "Table 'fashion_items' is empty."
32+
33+
# Clean up
34+
conn.close()
35+
os.remove(db_file)

0 commit comments

Comments
 (0)