Skip to content

Nano #3

Description

@marioperezfuertes-svg

#!/usr/bin/env bash
set -e

Crear estructura

mkdir -p .github/workflows app/templates tests

Archivos base

echo "pycache/
*.pyc
.env
test.db
venv/" > .gitignore

echo "DATABASE_URL=sqlite:///./test.db
HOST=0.0.0.0
PORT=8000" > .env

echo "fastapi
uvicorn[standard]
sqlmodel
jinja2
apscheduler
pytest
python-dotenv" > requirements.txt

echo "# Buscador FastAPI

Proyecto de ejemplo con FastAPI, SQLModel, Jinja2 y APScheduler." > README.md

echo "FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]" > Dockerfile

echo "web: uvicorn app.main:app --host 0.0.0.0 --port $PORT" > Procfile

CI

cat > .github/workflows/ci.yml << 'EOF'
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: pytest --maxfail=1 --disable-warnings -q
EOF

Código Python

echo "from fastapi import FastAPI, Request, Depends
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from app.database import init_db, get_session
from app import crud, scheduler

app = FastAPI()
templates = Jinja2Templates(directory="app/templates")

@app.on_event("startup")
async def on_startup():
init_db()
scheduler.start_scheduler()

@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})

@app.post("/search", response_class=HTMLResponse)
async def search(request: Request):
form = await request.form()
query = form.get("query", "")
results = crud.search_books(next(get_session()), query)
return templates.TemplateResponse("results.html", {
"request": request,
"query": query,
"results": results
})" > app/main.py

echo "from sqlmodel import SQLModel, create_engine, Session
import os

DATABASE_URL = os.getenv("DATABASE_URL")
engine = create_engine(DATABASE_URL, echo=True)

def init_db():
from app.models import Book
SQLModel.metadata.create_all(engine)

def get_session():
with Session(engine) as session:
yield session" > app/database.py

echo "from sqlmodel import SQLModel, Field

class Book(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
title: str
author: str
published_year: int" > app/models.py

echo "from sqlmodel import SQLModel

class BookCreate(SQLModel):
title: str
author: str
published_year: int" > app/schemas.py

echo "from sqlmodel import select
from .models import Book

def search_books(session, query: str):
stmt = select(Book).where(Book.title.contains(query))
return session.exec(stmt).all()" > app/crud.py

echo "from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()

def scheduled_task():
print("Tarea programada ejecutada.")

def start_scheduler():
scheduler.add_job(scheduled_task, "interval", hours=1)
scheduler.start()" > app/scheduler.py

echo "

<title>Buscador FastAPI</title>

Buscador de Libros

Buscar " > app/templates/index.html

echo "

<title>Resultados</title>

Resultados para '{{ query }}'

    {% for book in results %}
  • {{ book.title }} - {{ book.author }} ({{ book.published_year }})
  • {% else %}
  • No se encontraron libros.
  • {% endfor %}
Volver " > app/templates/results.html

echo "from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_read_root():
response = client.get("/")
assert response.status_code == 200

def test_search_no_results():
response = client.post("/search", data={"query": "NoExiste"})
assert response.status_code == 200
assert "No se encontraron libros" in response.text" > tests/test_main.py

echo "Proyecto generado correctamente ✅"

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions