feat: 🎉 starting from backend

This commit is contained in:
Michel Roux 2024-11-02 18:35:12 +01:00
commit 70cb30e9ff
8 changed files with 1575 additions and 0 deletions

166
.gitignore vendored Normal file
View File

@ -0,0 +1,166 @@
# 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/
# Mine
.ruff_cache/
*.sqlite

0
README.md Normal file
View File

0
backend/__init__.py Normal file
View File

8
backend/__main__.py Normal file
View File

@ -0,0 +1,8 @@
from dotenv import load_dotenv
from uvicorn import run
from .http import app
load_dotenv()
run(app, host="0.0.0.0")

38
backend/db.py Normal file
View File

@ -0,0 +1,38 @@
from os import environ
from typing import Iterator, Optional
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
DB_URL = environ.get("DB_URL", "sqlite:///pilotwings.sqlite")
engine = create_engine(DB_URL)
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
username: str = Field(unique=True)
password: str
containers: list["Container"] = Relationship(back_populates="user")
class Container(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(unique=True)
user_id: int = Field(foreign_key="user.id")
user: User = Relationship(back_populates="containers")
envs: str
def get_session() -> Iterator[Session]:
with Session(engine) as session:
yield session
def create_db_and_tables() -> None:
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
statement = select(User).where(User.username == "admin")
user = session.exec(statement).first()
if not user:
user = User(username="admin", password="admin")
session.add(user)
session.commit()

42
backend/http.py Normal file
View File

@ -0,0 +1,42 @@
from typing import Annotated
from fastapi import Depends, FastAPI, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from sqlmodel import Session, and_, select
from starlette.status import HTTP_403_FORBIDDEN
from .db import User, create_db_and_tables, engine, get_session
security = HTTPBasic()
def check_auth(credentials: Annotated[HTTPBasicCredentials, Depends(security)]) -> User:
with Session(engine) as session:
statement = select(User).where(
and_(
User.username == credentials.username,
User.password == credentials.password,
)
)
user = session.exec(statement).first()
if not user:
raise HTTPException(
status_code=HTTP_403_FORBIDDEN,
detail="Invalid authentication credentials",
)
return user
app = FastAPI(dependencies=[Depends(get_session), Depends(check_auth)])
@app.on_event("startup")
def on_startup() -> None:
create_db_and_tables()
@app.get("/")
def hello_world() -> str:
return "<p>Hello, World!</p>"

1295
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

26
pyproject.toml Normal file
View File

@ -0,0 +1,26 @@
[tool.poetry]
name = "backend"
version = "0.1.0"
description = ""
authors = ["Xéfir Destiny <xefir@crystalyx.net>"]
readme = "README.md"
[tool.poetry.dependencies]
python = ">=3.8"
fastapi = {extras = ["standard"], version = "^0.115.4"}
python-dotenv = "^1.0.1"
sqlmodel = "^0.0.22"
[tool.poetry.group.dev.dependencies]
mypy = "^1.13.0"
ruff = "^0.7.2"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.mypy]
strict = true
[tool.ruff.lint]
select = ["E", "F", "I", "UP"]