Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
[flake8]
# Maximum line length allowed
max-line-length = 127

# Maximum allowed code complexity (10 is a reasonable threshold)
max-line-length = 88
max-complexity = 10

# Only check for specific error codes:
# - E9 -> Syntax errors
# - F63 -> Issues related to improper usage of `+=`, `-=`, etc.
# - F7 -> Issues related to improper `break`, `continue`, etc.
# - F82 -> Undefined names
select = E9,F63,F7,F82

# Exclude `.venv` from linting (prevents checking dependencies)
select = E,F,W
extend-ignore = E203, W503
exclude = .venv

# Print the count of linting errors
per-file-ignores = tests/test_main.py: E501
count = True

# Show the exact source of the error
show-source = True

# Display statistics of errors at the end of the report
statistics = True

# Enable verbose mode for more detailed output
verbose = True
8 changes: 6 additions & 2 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'

- name: Install dependencies
- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-lint.txt
Expand All @@ -40,6 +40,10 @@ jobs:
run: |
flake8 .

- name: Check code formatting with Black
run: |
black --check .

test:
needs: lint
runs-on: ubuntu-latest
Expand All @@ -53,7 +57,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'

- name: Install dependencies
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-test.txt
Expand Down
1 change: 1 addition & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"recommendations": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"github.vscode-pull-request-github",
"github.vscode-github-actions",
"ms-azuretools.vscode-containers",
Expand Down
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
"**/.git": true,
"**/.DS_Store": true
},
"editor.wordWrapColumn": 88,
"editor.rulers": [88],
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8",
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
},
"sonarlint.connectedMode.project": {
Expand Down
57 changes: 36 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,58 @@ We value **incremental, detail‑first contributions** over big rewrites or abst
## 2. Code & Commit Conventions

- **Conventional Commits**
Follow <https://www.conventionalcommits.org/en/v1.0.0/>:
- `feat: ` for new features
- `fix: ` for bug fixes
- `chore: ` for maintenance
Follow <https://www.conventionalcommits.org/en/v1.0.0/>:
- `feat: ` for new features
- `fix: ` for bug fixes
- `chore: ` for maintenance or tooling

- **Logical Commits**
Group changes by purpose. It’s okay to have multiple commits in a PR, but if they’re mere checkpoints, squash them into a single logical commit.

- **Lint & Tests**
Run existing linters/formatters and ensure all tests pass.
Group changes by purpose. Multiple commits are fine, but avoid noise. Squash when appropriate.

- **Python Formatting & Style**
- Use **[Black](https://black.readthedocs.io/)** for consistent code formatting.
- Black is opinionated: don't argue with it, just run it.
- Line length is set to **88**, matching the default.
- Use **[flake8](https://flake8.pycqa.org/en/latest/)** for static checks.
- Line length also set to 88.
- Some flake8 warnings are disabled (e.g. `E203`, `W503`) to avoid conflicts with Black.
- Run `black .` and `flake8` before submitting.
- Use Python **3.13.x** for local testing and formatting.

- **Testing**
- Run `pytest` before pushing.
- Ensure coverage isn’t regressing.

## 3. Pull Request Workflow

- **One logical change per PR.**
- **Rebase or squash** before opening to keep history concise.
- **Rebase or squash** before opening to keep history clean.
- **Title & Description**
- Title uses Conventional Commits style.
- Description explains _what_ and _why_—keep context minimal.
- Use Conventional Commit format.
- Explain _what_ and _why_ concisely in the PR body.

## 4. Issue Reporting

- Search existing issues first.
- Provide a minimal reproducible example and clear steps.
- Search open issues before creating a new one.
- Include clear steps to reproduce and environment details.
- Prefer **focused** issues—don’t bundle multiple topics.

## 5. Automation & Checks

We enforce quality via CI on every push and PR:
All PRs and pushes go through CI:

- **Commitlint** for commit‑message style
- **Linters/Formatters**
- **Unit tests**
- **Commitlint** for commit style
- **Black** for formatting
- **flake8** for static checks
- **pytest** with coverage

Failures must be fixed before review.
PRs must pass all checks to be reviewed.

## 6. Code of Conduct & Support

- Please see `CODE_OF_CONDUCT.md` for behavioral expectations and reporting.
- For quick questions or discussions, open an issue with the `discussion` label or mention a maintainer.
- See `CODE_OF_CONDUCT.md` for guidelines and reporting.
- For questions or planning, open an issue and use the `discussion` label, or mention a maintainer.

---

Thanks again for helping keep this project small, simple, and impactful!
Thanks again for helping keep this project small, sharp, and focused.
10 changes: 3 additions & 7 deletions databases/player_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

The `STORAGE_PATH` environment variable controls the SQLite file location.
"""

import logging
import os
from typing import AsyncGenerator
Expand All @@ -21,16 +22,11 @@
logging.getLogger("sqlalchemy.engine.Engine").handlers = logger.handlers

async_engine = create_async_engine(
DATABASE_URL,
connect_args={"check_same_thread": False},
echo=True
DATABASE_URL, connect_args={"check_same_thread": False}, echo=True
)

async_sessionmaker = sessionmaker(
bind=async_engine,
class_=AsyncSession,
autocommit=False,
autoflush=False
bind=async_engine, class_=AsyncSession, autocommit=False, autoflush=False
)

Base = declarative_base()
Expand Down
13 changes: 9 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

This serves as the entry point for running the API server.
"""

from contextlib import asynccontextmanager
import logging
from typing import AsyncIterator
Expand All @@ -17,6 +18,7 @@
UVICORN_LOGGER = "uvicorn.error"
logger = logging.getLogger(UVICORN_LOGGER)


@asynccontextmanager
async def lifespan(_: FastAPI) -> AsyncIterator[None]:
"""
Expand All @@ -25,10 +27,13 @@ async def lifespan(_: FastAPI) -> AsyncIterator[None]:
logger.info("Lifespan event handler execution complete.")
yield

app = FastAPI(lifespan=lifespan,
title="python-samples-fastapi-restful",
description="🧪 Proof of Concept for a RESTful API made with Python 3 and FastAPI",
version="1.0.0",)

app = FastAPI(
lifespan=lifespan,
title="python-samples-fastapi-restful",
description="🧪 Proof of Concept for a RESTful API made with Python 3 and FastAPI",
version="1.0.0",
)

app.include_router(player_route.api_router)
app.include_router(health_route.api_router)
3 changes: 3 additions & 0 deletions models/player_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

These models are used for data validation and serialization in the API.
"""

from typing import Optional
from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_camel
Expand All @@ -24,6 +25,7 @@ class MainModel(BaseModel):
Here, it uses `to_camel` to convert field names to camelCase.
populate_by_name (bool): Allows population of fields by name when using Pydantic models.
"""

model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)


Expand All @@ -44,6 +46,7 @@ class PlayerModel(MainModel):
league (Optional[str]): The league where the team plays, if any.
starting11 (Optional[bool]): Indicates if the Player is in the starting 11, if provided.
"""

id: int
first_name: str
middle_name: Optional[str]
Expand Down
20 changes: 20 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool.black]
line-length = 88
target-version = ['py313']
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.github
| \.pytest_cache
| \.venv
| \.vscode
| assets
| htmlcov
| postman_collections
| scripts
| storage
| __pycache__
| tests/test_main\.py
)/
'''
1 change: 1 addition & 0 deletions requirements-lint.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
flake8==7.2.0
black==25.1.0
2 changes: 2 additions & 0 deletions routes/health_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
Defines a simple endpoint to verify that the service is up and running.
Returns a JSON response with a "status" key set to "ok".
"""

from fastapi import APIRouter

api_router = APIRouter()


@api_router.get("/health", tags=["Health"])
async def health_check():
"""
Expand Down
Loading
Loading