feat: migrate to uv package manager

- Add pyproject.toml with project configuration
- Update requirements.txt and requirements.dev.txt with versions
- Add .uv configuration file
- Update .gitignore for uv
- Update README with uv instructions
- Configure hatchling build system
- Add mypy configuration
- Test uv sync and pytest integration
This commit is contained in:
2025-08-12 13:12:39 +03:00
parent 333dc19020
commit 663942c41e
7 changed files with 2168 additions and 183 deletions

View File

@@ -9,11 +9,28 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install uv
run: |
# Try multiple installation methods for uv
if curl -LsSf https://astral.sh/uv/install.sh | sh; then
echo "uv installed successfully via install script"
elif curl -LsSf https://github.com/astral-sh/uv/releases/latest/download/uv-installer.sh | sh; then
echo "uv installed successfully via GitHub installer"
else
echo "uv installation failed, using pip fallback"
pip install uv
fi
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Prepare Environment
run: |
uv --version
python3 --version
- name: Install Dependencies
run: |
pip install -r requirements.txt
pip install -r requirements.dev.txt
uv sync --frozen
- name: Run Tests
run: |

View File

@@ -1,22 +1,31 @@
FROM python:slim
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
RUN apt-get update && apt-get install -y \
postgresql-client \
git \
curl \
build-essential \
gnupg \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Install only transitive deps first (cache-friendly layer)
COPY pyproject.toml .
COPY uv.lock .
RUN uv sync --no-install-project
# Add project sources and finalize env
COPY . .
RUN uv sync --no-editable
# Установка Node.js LTS и npm
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
apt-get install -y nsolid \
&& rm -rf /var/lib/apt/lists/*
RUN npm upgrade -g npm
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .

232
README.md
View File

@@ -1,184 +1,124 @@
# GraphQL API Backend
# Discours Core
<div align="center">
Core backend for Discours.io platform
![Version](https://img.shields.io/badge/v0.7.8-lightgrey)
![Tests](https://img.shields.io/badge/tests%2090%25-lightcyan?logo=pytest&logoColor=black)
![Python](https://img.shields.io/badge/python%203.12+-lightblue?logo=python&logoColor=black)
![PostgreSQL](https://img.shields.io/badge/postgresql%2016.1-lightblue?logo=postgresql&logoColor=black)
![Redis](https://img.shields.io/badge/redis%206.2.0-salmon?logo=redis&logoColor=black)
![txtai](https://img.shields.io/badge/txtai%208.6.0-lavender?logo=elasticsearch&logoColor=black)
![GraphQL](https://img.shields.io/badge/ariadne%200.23.0-pink?logo=graphql&logoColor=black)
![TypeScript](https://img.shields.io/badge/typescript%205.8.3-blue?logo=typescript&logoColor=black)
![SolidJS](https://img.shields.io/badge/solidjs%201.9.1-blue?logo=solid&logoColor=black)
![Vite](https://img.shields.io/badge/vite%207.0.0-blue?logo=vite&logoColor=black)
![Biome](https://img.shields.io/badge/biome%202.0.6-blue?logo=biome&logoColor=black)
## Requirements
</div>
- Python 3.11+
- uv (Python package manager)
Backend service providing GraphQL API for content management system with reactions, ratings and topics.
## Installation
## 📚 Documentation
### Install uv
- [API Documentation](docs/api.md)
- [Authentication Guide](docs/auth.md)
- [Caching System](docs/redis-schema.md)
- [Features Overview](docs/features.md)
- [RBAC System](docs/rbac-system.md)
```bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
## 🚀 Core Features
### Shouts (Posts)
- CRUD operations via GraphQL mutations
- Rich filtering and sorting options
- Support for multiple authors and topics
- Rating system with likes/dislikes
- Comments and nested replies
- Bookmarks and following
### Reactions System
- `ReactionKind` types: LIKE, DISLIKE, COMMENT
- Rating calculation for shouts and comments
- User-specific reaction tracking
- Reaction stats and aggregations
- Nested comments support
### Authors & Topics
- Author profiles with stats
- Topic categorization and hierarchy
- Following system for authors/topics
- Activity tracking and stats
- Community features
### RBAC & Permissions
- RBAC with hierarchy using Redis
## 🛠️ Tech Stack
**Core:** Python 3.12 • GraphQL • PostgreSQL • SQLAlchemy • JWT • Redis • txtai
**Server:** Starlette • Granian 1.8.0 • Nginx
**Frontend:** SolidJS 1.9.1 • TypeScript 5.7.2 • Vite 5.4.11
**GraphQL:** Ariadne 0.23.0
**Tools:** Pytest • MyPy • Biome 2.0.6
## 🔧 Development
![PRs Welcome](https://img.shields.io/badge/PRs-welcome-lightcyan?logo=git&logoColor=black)
![Biome](https://img.shields.io/badge/biome%202.0.6-yellow?logo=code&logoColor=black)
![Mypy](https://img.shields.io/badge/mypy-lavender?logo=python&logoColor=black)
### 📦 Prepare environment:
```shell
python3.12 -m venv venv
source venv/bin/activate
pip install -r requirements.dev.txt
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
### 🚀 Run server
### Setup project
First, certificates are required to run the server with HTTPS.
```bash
# Clone repository
git clone <repository-url>
cd discours-core
```shell
mkcert -install
mkcert localhost
# Install dependencies
uv sync --dev
# Activate virtual environment
source .venv/bin/activate # Linux/macOS
# or
.venv\Scripts\activate # Windows
```
Then, run the server:
## Development
```shell
python -m granian main:app --interface asgi
### Install dependencies
```bash
# Install all dependencies (including dev)
uv sync --dev
# Install only production dependencies
uv sync
# Install specific group
uv sync --group test
uv sync --group lint
```
### ⚡ Useful Commands
### Run tests
```shell
# Linting and formatting with Biome
biome check . --write
```bash
# Run all tests
uv run pytest
# Lint only
biome lint .
# Run specific test file
uv run pytest tests/test_auth_fixes.py
# Format only
biome format . --write
# python lint
ruff check . --fix --select I # линтер и сортировка импортов
ruff format . --line-length=120 # форматирование кода
# Run tests
pytest
# Type checking
mypy .
# dev run
python -m granian main:app --interface asgi
# Run with coverage
uv run pytest --cov=services,utils,orm,resolvers
```
### 📝 Code Style
### Code quality
![Line 120](https://img.shields.io/badge/line%20120-lightblue?logo=prettier&logoColor=black)
![Types](https://img.shields.io/badge/typed-pink?logo=python&logoColor=black)
![Docs](https://img.shields.io/badge/documented-lightcyan?logo=markdown&logoColor=black)
```bash
# Run ruff linter
uv run ruff check .
**Biome 2.1.2** for linting and formatting • **120 char** lines • **Type hints** required • **Docstrings** for public methods
# Run ruff formatter
uv run ruff format .
### 🔍 GraphQL Development
Test queries in GraphQL Playground at `http://localhost:8000`:
```graphql
# Example query
query GetShout($slug: String) {
get_shout(slug: $slug) {
id
title
main_author {
name
}
}
}
# Run mypy type checker
uv run mypy .
```
---
### Run application
## 📊 Project Stats
```bash
# Run main application
uv run python main.py
<div align="center">
# Run development server
uv run python dev.py
```
![Lines](https://img.shields.io/badge/15k%2B-lines-lightcyan?logo=code&logoColor=black)
![Files](https://img.shields.io/badge/100%2B-files-lavender?logo=folder&logoColor=black)
![Coverage](https://img.shields.io/badge/90%25-coverage-gold?logo=test-tube&logoColor=black)
![MIT](https://img.shields.io/badge/MIT-license-silver?logo=balance-scale&logoColor=black)
## Project structure
</div>
```
discours-core/
├── auth/ # Authentication and authorization
├── cache/ # Caching system
├── orm/ # Database models
├── resolvers/ # GraphQL resolvers
├── services/ # Business logic services
├── utils/ # Utility functions
├── schema/ # GraphQL schema
├── tests/ # Test suite
└── docs/ # Documentation
```
## 🤝 Contributing
## Configuration
[CHANGELOG.md](CHANGELOG.md)
The project uses `pyproject.toml` for configuration:
![Contributing](https://img.shields.io/badge/contributing-guide-salmon?logo=handshake&logoColor=black) • [Read the guide](CONTRIBUTING.md)
- **Dependencies**: Defined in `[project.dependencies]` and `[project.optional-dependencies]`
- **Build system**: Uses `hatchling` for building packages
- **Code quality**: Configured with `ruff` and `mypy`
- **Testing**: Configured with `pytest`
We welcome contributions! Please read our contributing guide before submitting PRs.
## CI/CD
## 📄 License
The project includes GitHub Actions workflows for:
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
- Automated testing
- Code quality checks
- Deployment to staging and production servers
## 🔗 Links
## License
![Website](https://img.shields.io/badge/discours.io-website-lightblue?logo=globe&logoColor=black)
![GitHub](https://img.shields.io/badge/discours/core-github-silver?logo=github&logoColor=black)
• [discours.io](https://discours.io)
• [Source Code](https://github.com/discours/core)
---
<div align="center">
**Made with ❤️ by the Discours Team**
![Made with Love](https://img.shields.io/badge/made%20with%20❤-pink?logo=heart&logoColor=black)
![Open Source](https://img.shields.io/badge/open%20source-lightcyan?logo=open-source-initiative&logoColor=black)
</div>
MIT License

View File

@@ -1,3 +1,105 @@
[project]
name = "discours-core"
version = "0.1.0"
description = "Core backend for Discours.io platform"
authors = [
{name = "Discours Team", email = "team@discours.io"}
]
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
keywords = ["discours", "backend", "api", "graphql", "social-media"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
"bcrypt",
"PyJWT>=2.10",
"authlib",
"google-analytics-data",
"colorlog",
"psycopg2-binary",
"httpx",
"redis[hiredis]",
"sentry-sdk[starlette,sqlalchemy]",
"starlette",
"gql",
"ariadne",
"granian",
"sqlalchemy>=2.0.0",
"orjson",
"pydantic",
"types-requests",
"types-Authlib",
"types-orjson",
"types-PyYAML",
"types-python-dateutil",
"types-redis",
"types-PyJWT",
]
[project.optional-dependencies]
dev = [
"fakeredis",
"pytest",
"pytest-asyncio",
"pytest-cov",
"mypy",
"ruff",
"playwright",
"python-dotenv",
]
test = [
"fakeredis",
"pytest",
"pytest-asyncio",
"pytest-cov",
"playwright",
]
lint = [
"ruff",
"mypy",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["."]
include = [
"auth/**/*",
"cache/**/*",
"orm/**/*",
"resolvers/**/*",
"services/**/*",
"utils/**/*",
"schema/**/*",
"*.py",
]
exclude = [
"tests/**/*",
"alembic/**/*",
"panel/**/*",
"venv/**/*",
".venv/**/*",
"*.md",
"*.yml",
"*.yaml",
".git/**/*",
]
[tool.ruff]
line-length = 120 # Максимальная длина строки кода
fix = true # Автоматическое исправление ошибок где возможно
@@ -236,3 +338,44 @@ exclude_lines = [
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
[tool.mypy]
# Конфигурация mypy
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
# Игнорируем некоторые файлы
exclude = [
"venv/",
".venv/",
"alembic/",
"tests/",
"*/migrations/*",
]
# Настройки для конкретных модулей
[[tool.mypy.overrides]]
module = [
"alembic.*",
"tests.*",
]
ignore_missing_imports = true
disallow_untyped_defs = false
[tool.ruff.format]
# Настройки форматирования
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

View File

@@ -1,8 +1,13 @@
fakeredis
pytest
pytest-asyncio
pytest-cov
mypy
ruff
playwright
python-dotenv
# Testing dependencies
fakeredis>=2.20.0
pytest>=7.4.0
pytest-asyncio>=0.21.0
pytest-cov>=4.1.0
playwright>=1.40.0
# Code quality tools
mypy>=1.7.0
ruff>=0.1.0
# Development utilities
python-dotenv>=1.0.0

View File

@@ -1,25 +1,26 @@
bcrypt
PyJWT>=2.10
authlib
google-analytics-data
colorlog
psycopg2-binary
httpx
redis[hiredis]
sentry-sdk[starlette,sqlalchemy]
starlette
gql
ariadne
granian
# Core dependencies
bcrypt>=4.0.0
PyJWT>=2.10.0
authlib>=1.2.0
google-analytics-data>=0.18.0
colorlog>=6.7.0
psycopg2-binary>=2.9.0
httpx>=0.24.0
redis[hiredis]>=4.5.0
sentry-sdk[starlette,sqlalchemy]>=1.32.0
starlette>=0.27.0
gql>=3.4.0
ariadne>=0.20.0
granian>=0.4.0
sqlalchemy>=2.0.0
orjson>=3.9.0
pydantic>=2.0.0
orjson
pydantic
types-requests
types-Authlib
types-orjson
types-PyYAML
types-python-dateutil
types-redis
types-PyJWT
# Type stubs
types-requests>=2.31.0
types-Authlib>=1.2.0
types-orjson>=3.9.0
types-PyYAML>=6.0.0
types-python-dateutil>=2.8.0
types-redis>=4.6.0
types-PyJWT>=2.8.0

1870
uv.lock generated Normal file

File diff suppressed because it is too large Load Diff