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:
@@ -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: |
|
||||
|
||||
17
Dockerfile
17
Dockerfile
@@ -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
232
README.md
@@ -1,184 +1,124 @@
|
||||
# GraphQL API Backend
|
||||
# Discours Core
|
||||
|
||||
<div align="center">
|
||||
Core backend for Discours.io platform
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
## 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
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### 📦 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
|
||||
|
||||

|
||||

|
||||

|
||||
```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
|
||||
```
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
## 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:
|
||||
|
||||
 • [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
|
||||
|
||||

|
||||

|
||||
• [discours.io](https://discours.io)
|
||||
• [Source Code](https://github.com/discours/core)
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
**Made with ❤️ by the Discours Team**
|
||||
|
||||

|
||||

|
||||
|
||||
</div>
|
||||
MIT License
|
||||
|
||||
143
pyproject.toml
143
pyproject.toml
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user