wip
This commit is contained in:
parent
6b1c60a550
commit
839cbd0dc0
17 changed files with 213 additions and 35 deletions
6
.pyflyby
6
.pyflyby
|
|
@ -7,7 +7,13 @@ from learn_sql_model.console import console
|
|||
# models
|
||||
|
||||
from learn_sql_model.models.fast_model import FastModel
|
||||
|
||||
from learn_sql_model.models.hero import Hero
|
||||
from learn_sql_model.models.hero import HeroCreate
|
||||
from learn_sql_model.models.hero import HeroRead
|
||||
from learn_sql_model.models.hero import HeroUpdate
|
||||
from learn_sql_model.models.hero import HeroDelete
|
||||
|
||||
from learn_sql_model.factories.hero import HeroFactory
|
||||
from learn_sql_model.factories.pet import PetFactory
|
||||
from learn_sql_model.models.pet import Pet
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
from python:3.10
|
||||
|
||||
# install python and psycopg2
|
||||
# RUN apt-get update && apt-get install -y python3 python3-pip
|
||||
# RUN pip3 install hatch
|
||||
WORKDIR /app
|
||||
Copy pyproject.toml /app
|
||||
COPY learn_sql_model/__about__.py /app/learn_sql_model/__about__.py
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM learn-sql-model
|
||||
FROM python:3.10
|
||||
|
||||
ENV DEBIAIN_FRONTEND=noninteractive
|
||||
ENV PATH="$PATH:/root/.local/bin:/root/.cargo/bin"
|
||||
|
|
@ -43,11 +43,20 @@ RUN python3 -m pip install --upgrade pip && \
|
|||
|
||||
WORKDIR /app
|
||||
|
||||
## DUPLICATE from Dockerfile
|
||||
## building FROM learn-sql-model will cause the cache to bust for every
|
||||
## change, it needs to come after the dev installs.
|
||||
COPY pyproject.toml /app
|
||||
COPY learn_sql_model/__about__.py /app/learn_sql_model/__about__.py
|
||||
COPY README.md /app
|
||||
RUN pip3 install .
|
||||
COPY . .
|
||||
RUN python3 -m hatch env create && \
|
||||
python3 -m hatch shell
|
||||
|
||||
|
||||
RUN stow bin -t /root/
|
||||
|
||||
COPY .env.dev.docker /app/.env.dev
|
||||
|
||||
|
||||
ENTRYPOINT /tmp/zellij/bootstrap/zellij
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -9,6 +9,19 @@ pip install hatch
|
|||
hatch shell
|
||||
```
|
||||
|
||||
## Development with Docker
|
||||
|
||||
```console
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
To attach to the cli.
|
||||
|
||||
```console
|
||||
docker attach learn-sql-model-cli-1
|
||||
```
|
||||
|
||||
## Start the Server
|
||||
|
||||
```console
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne
|
|||
# are written from script.py.mako
|
||||
# output_encoding = utf-8
|
||||
|
||||
sqlalchemy.url = sqlite:///database.db
|
||||
sqlalchemy.url = postgresql+psycopg2://postgres:postgres@localhost:5432
|
||||
|
||||
|
||||
[post_write_hooks]
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ services:
|
|||
restart: always
|
||||
tty: true
|
||||
stdin_open: true
|
||||
volumes:
|
||||
- ./:/app
|
||||
volumes:
|
||||
db:
|
||||
driver: local
|
||||
|
|
|
|||
48
dockerfile-dev
Normal file
48
dockerfile-dev
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
FROM learn-sql-model
|
||||
|
||||
ENV DEBIAIN_FRONTEND=noninteractive
|
||||
ENV PATH="$PATH:/root/.local/bin:/root/.cargo/bin"
|
||||
ENV SHELL=zsh
|
||||
ENV USER=root
|
||||
|
||||
|
||||
RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y \
|
||||
cmake \
|
||||
htop \
|
||||
stow \
|
||||
zsh
|
||||
|
||||
|
||||
WORKDIR /root/downloads
|
||||
|
||||
RUN wget https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage && \
|
||||
mkdir -p /root/.local/bin && \
|
||||
chmod u+x /root/downloads/nvim.appimage && \
|
||||
/root/downloads/nvim.appimage --appimage-extract && \
|
||||
rm -rf nvim.appimage && \
|
||||
ln -s ~/downloads/squashfs-root/usr/bin/nvim ~/.local/bin/nvim && \
|
||||
cd ~ && \
|
||||
git clone https://github.com/LazyVim/starter ~/.config/nvim && \
|
||||
nvim --headless -c 'quitall'
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly -y && \
|
||||
cargo install \
|
||||
bat \
|
||||
exa \
|
||||
gitui \
|
||||
ripgrep \
|
||||
starship \
|
||||
zellij
|
||||
|
||||
RUN python3 -m pip install --upgrade pip && \
|
||||
python3 -m pip install ansible-core && \
|
||||
python3 -m pip install lolcat && \
|
||||
python3 -m pip install pyflyby && \
|
||||
python3 -m pip install rich-cli && \
|
||||
python3 -m pip install visidata
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENTRYPOINT zellij
|
||||
|
|
@ -11,8 +11,8 @@ hero_router = APIRouter()
|
|||
|
||||
|
||||
@hero_router.on_event("startup")
|
||||
def on_startup(config: Config = Depends(get_config)) -> None:
|
||||
SQLModel.metadata.create_all(config.database.engine)
|
||||
def on_startup() -> None:
|
||||
SQLModel.metadata.create_all(get_config().database.engine)
|
||||
|
||||
|
||||
@hero_router.get("/items/")
|
||||
|
|
@ -26,6 +26,12 @@ def get_hero(id: int, config: Config = Depends(get_config)) -> Hero:
|
|||
return Hero().get(id=id, config=config)
|
||||
|
||||
|
||||
@hero_router.get("/h/{id}")
|
||||
def get_h(id: int, config: Config = Depends(get_config)) -> Hero:
|
||||
"get one hero"
|
||||
return Hero().get(id=id, config=config)
|
||||
|
||||
|
||||
@hero_router.post("/hero/")
|
||||
def post_hero(hero: Hero, config: Config = Depends(get_config)) -> Hero:
|
||||
"read all the heros"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from rich.console import Console
|
||||
import typer
|
||||
import uvicorn
|
||||
|
||||
|
|
@ -27,3 +28,38 @@ def run(
|
|||
),
|
||||
):
|
||||
uvicorn.run(**get_config().api_server.dict())
|
||||
|
||||
|
||||
@api_app.command()
|
||||
def status(
|
||||
verbose: bool = typer.Option(
|
||||
False,
|
||||
callback=verbose_callback,
|
||||
help="show the log messages",
|
||||
),
|
||||
):
|
||||
import httpx
|
||||
|
||||
config = get_config()
|
||||
host = config.api_server.host
|
||||
port = config.api_server.port
|
||||
url = f"http://{host}:{port}/docs"
|
||||
|
||||
try:
|
||||
r = httpx.get(url)
|
||||
if r.status_code == 200:
|
||||
Console().print(f"[green]API: ([gold1]{url}[green]) is running")
|
||||
else:
|
||||
Console().print(f"[red]API: ([gold1]{url}[red]) is not running")
|
||||
except httpx.ConnectError:
|
||||
Console().print(f"[red]API: ([gold1]{url}[red]) is not running")
|
||||
|
||||
try:
|
||||
with config.database.engine.connect():
|
||||
Console().print(
|
||||
f"[green]database: ([gold1]{config.database.engine}[green]) is running"
|
||||
)
|
||||
except Exception as e:
|
||||
Console().print(
|
||||
f"[red]database: ([gold1]{config.database.engine}[red]) is not running"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,16 +5,14 @@ from typer.main import get_group
|
|||
from learn_sql_model.cli.api import api_app
|
||||
from learn_sql_model.cli.config import config_app
|
||||
from learn_sql_model.cli.hero import hero_app
|
||||
from learn_sql_model.cli.model import model_app
|
||||
from learn_sql_model.cli.tui import tui_app
|
||||
|
||||
app = typer.Typer(
|
||||
name="learn_sql_model",
|
||||
help="learn-sql-model cli for managing the project",
|
||||
)
|
||||
app.add_typer(config_app, name="config")
|
||||
app.add_typer(tui_app, name="tui")
|
||||
app.add_typer(model_app, name="model")
|
||||
# app.add_typer(tui_app, name="tui")
|
||||
# app.add_typer(model_app, name="model")
|
||||
app.add_typer(api_app, name="api")
|
||||
app.add_typer(hero_app, name="hero")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
import sys
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from pydantic_typer import expand_pydantic_args
|
||||
from engorgio import engorgio
|
||||
from rich.console import Console
|
||||
import typer
|
||||
|
||||
from learn_sql_model.config import Config
|
||||
from learn_sql_model.config import Config, get_config
|
||||
from learn_sql_model.factories.hero import HeroFactory
|
||||
from learn_sql_model.factories.pet import PetFactory
|
||||
from learn_sql_model.models.hero import Hero
|
||||
from learn_sql_model.models.pet import Pet
|
||||
import sys
|
||||
from learn_sql_model.models.hero import Hero, HeroCreate
|
||||
|
||||
hero_app = typer.Typer()
|
||||
|
||||
|
|
@ -20,9 +19,9 @@ def hero():
|
|||
|
||||
|
||||
@hero_app.command()
|
||||
@expand_pydantic_args(typer=True)
|
||||
@engorgio(typer=True)
|
||||
def get(
|
||||
id: Optional[int] = None,
|
||||
id: Optional[int] = typer.Argument(default=None),
|
||||
config: Config = None,
|
||||
) -> Union[Hero, List[Hero]]:
|
||||
"get one hero"
|
||||
|
|
@ -33,28 +32,36 @@ def get(
|
|||
|
||||
|
||||
@hero_app.command()
|
||||
@expand_pydantic_args(typer=True)
|
||||
@engorgio(typer=True)
|
||||
def list(
|
||||
config: Config = None,
|
||||
) -> Union[Hero, List[Hero]]:
|
||||
"get one hero"
|
||||
hero = Hero().get()
|
||||
Console().print(hero)
|
||||
return hero
|
||||
|
||||
|
||||
@hero_app.command()
|
||||
@engorgio(typer=True)
|
||||
def create(
|
||||
hero: Hero,
|
||||
pet: Pet = None,
|
||||
hero: HeroCreate,
|
||||
config: Config = None,
|
||||
) -> Hero:
|
||||
"read all the heros"
|
||||
config.init()
|
||||
hero.pet = pet
|
||||
hero = hero.post(config=config)
|
||||
Console().print(hero)
|
||||
|
||||
|
||||
@hero_app.command()
|
||||
@expand_pydantic_args(typer=True)
|
||||
@engorgio(typer=True)
|
||||
def populate(
|
||||
hero: Hero,
|
||||
n: int = 10,
|
||||
config: Config = None,
|
||||
) -> Hero:
|
||||
"read all the heros"
|
||||
if config is None:
|
||||
config = Config()
|
||||
config = get_config()
|
||||
if config.env == "prod":
|
||||
Console().print("populate is not supported in production")
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ from learn_sql_model.models.fast_model import FastModel
|
|||
from learn_sql_model.models.pet import Pet
|
||||
|
||||
|
||||
class Hero(FastModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
class HeroBase(FastModel, table=False):
|
||||
name: str
|
||||
secret_name: str
|
||||
age: Optional[int] = None
|
||||
|
|
@ -15,3 +14,23 @@ class Hero(FastModel, table=True):
|
|||
|
||||
pet_id: Optional[int] = Field(default=None, foreign_key="pet.id")
|
||||
pet: Optional[Pet] = Relationship(back_populates="hero")
|
||||
|
||||
|
||||
class Hero(HeroBase, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
|
||||
|
||||
class HeroCreate(HeroBase):
|
||||
...
|
||||
|
||||
|
||||
class HeroRead(HeroBase):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
|
||||
|
||||
class HeroUpdate(HeroBase):
|
||||
...
|
||||
|
||||
|
||||
class HeroDelete(HeroBase):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from datetime import datetime
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from sqlmodel import Field, Relationship
|
||||
|
|
@ -11,4 +12,5 @@ if TYPE_CHECKING:
|
|||
class Pet(FastModel, table=True):
|
||||
id: Optional[int] = Field(default=None, primary_key=True)
|
||||
name: str = "Jim"
|
||||
birthday: Optional[datetime] = None
|
||||
hero: "Hero" = Relationship(back_populates="pet")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from alembic import context
|
|||
from sqlalchemy import engine_from_config, pool
|
||||
from sqlmodel import SQLModel
|
||||
|
||||
from learn_sql_model.config import get_config
|
||||
from learn_sql_model.models.hero import Hero
|
||||
from learn_sql_model.models.pet import Pet
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ def run_migrations_offline() -> None:
|
|||
script output.
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
url = get_config().database_url
|
||||
context.configure(
|
||||
url=url,
|
||||
target_metadata=target_metadata,
|
||||
|
|
@ -78,7 +79,7 @@ def run_migrations_online() -> None:
|
|||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=target_metadata,
|
||||
render_as_batch=True,
|
||||
render_as_batch=False,
|
||||
version_table=f'{config.get_main_option("project")}_alembic_version',
|
||||
)
|
||||
|
||||
|
|
|
|||
29
migrations/versions/a9bb6625c57b_add_birthday.py
Normal file
29
migrations/versions/a9bb6625c57b_add_birthday.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
"""add birthday
|
||||
|
||||
Revision ID: a9bb6625c57b
|
||||
Revises: c8516c888495
|
||||
Create Date: 2023-05-25 19:00:58.137464
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'a9bb6625c57b'
|
||||
down_revision = 'c8516c888495'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('pet', sa.Column('birthday', sa.DateTime(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('pet', 'birthday')
|
||||
# ### end Alembic commands ###
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
"""init
|
||||
|
||||
Revision ID: 2a221363b5f8
|
||||
Revision ID: c8516c888495
|
||||
Revises:
|
||||
Create Date: 2023-05-21 20:52:12.693194
|
||||
Create Date: 2023-05-25 18:42:37.057225
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
|
|
@ -11,7 +11,7 @@ import sqlmodel
|
|||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '2a221363b5f8'
|
||||
revision = 'c8516c888495'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
|
@ -25,16 +25,19 @@ classifiers = [
|
|||
]
|
||||
dependencies = [
|
||||
"anyconfig",
|
||||
"trogon",
|
||||
"engorgio",
|
||||
"fastapi",
|
||||
"httpx",
|
||||
"passlib[bcrypt]",
|
||||
"polyfactory",
|
||||
"psycopg2",
|
||||
"python-jose[cryptography]",
|
||||
"python-multipart",
|
||||
"rich",
|
||||
"sqlmodel",
|
||||
"textual",
|
||||
"toml",
|
||||
"trogon",
|
||||
"typer",
|
||||
"uvicorn[standard]",
|
||||
]
|
||||
|
|
@ -49,6 +52,7 @@ Changelog = "https://github.com/waylonwalker/learn-sql-model"
|
|||
|
||||
[project.scripts]
|
||||
learn-sql-model = "learn_sql_model.cli.app:app"
|
||||
lsm = "learn_sql_model.cli.app:app"
|
||||
|
||||
[tool.hatch.version]
|
||||
path = "learn_sql_model/__about__.py"
|
||||
|
|
@ -82,6 +86,7 @@ lint-test = [
|
|||
"cov",
|
||||
]
|
||||
test-lint = "lint-test"
|
||||
api = "learn-sql-model api run"
|
||||
|
||||
[[tool.hatch.envs.test.matrix]]
|
||||
python = ["37", "38", "39", "310", "311"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue