Thank you for considering contributing to Confy App! This project was developed with dedication by Brazilian students 🇧🇷 and we value all contributions, whether they are bug fixes, new features, documentation improvements, or tests.
To ensure an organized workflow and a good experience for everyone, please follow the guidelines below.
- Code of Conduct
- Getting Started
- Development Environment Setup
- Project Structure
- Contribution Workflow
- Code Standards
- Quality Tools
- Testing the App
- Running the Project Locally
- Creating a Pull Request
- Review Process
- Reporting Security Issues
We are committed to maintaining a welcoming, safe, and collaborative environment. Everyone should be treated with respect, regardless of age, gender identity, sexual orientation, ethnicity, religion, or experience level.
Unacceptable behaviors include:
- Harassment, discrimination, or insults
- Sexualized language or content
- Threats or personal attacks
- Unauthorized disclosure of private information
To report violations, contact: confy@henriquesebastiao.com
Before you begin, make sure you have:
- Git installed and configured
- Python 3.13 or higher (we support Python 3.13+)
- Poetry for dependency management (recommended)
- A GitHub account
python --version
poetry --version
git --version- Go to github.com/confy-security/app
- Click the "Fork" button in the top right corner
- This will create a copy of the repository in your account
git clone https://github.com/YOUR-USERNAME/app.git
cd appgit remote add upstream https://github.com/confy-security/app.git
git remote -v
# Verify you have 'origin' and 'upstream'poetry installThis command will:
- Create a virtual environment (if it doesn't exist)
- Install all main and development dependencies
- Automatically activate the virtual environment
If the environment was not activated automatically:
poetry shellOr execute commands within the environment with:
poetry run <command>app/
├── .github/
│ ├── CODEOWNERS (Code owners)
│ ├── dependabot.yml (Dependabot configuration)
│ └── workflows/
│ └── test.yml (Test pipeline)
├── confy/
│ ├── __init__.py (Main package)
│ ├── __main__.py (App entry point)
│ ├── labels.py (UI label definitions)
│ ├── qss.py (Qt stylesheets)
│ ├── utils.py (Utility functions)
│ ├── assets/ (Images and resources)
│ ├── ui/ (UI components)
│ │ ├── __init__.py
│ │ ├── chat.py
│ │ ├── connect_to_server.py
│ │ └── connect_to_user.py
│ └── core/
│ ├── __init__.py
│ └── constants.py (Project constants)
├── tests/
│ ├── __init__.py
│ ├── confy.py (Main tests)
│ └── test_connect_to_server.py
├── CONTRIBUTING.md (This file)
├── CODE_OF_CONDUCT.md
├── SECURITY.md
├── README.md
├── pyproject.toml (Poetry and project config)
├── poetry.lock (Dependency lock file)
└── LICENSE
Always create a separate branch for each contribution:
# Update from the main branch
git checkout main
git pull upstream main
# Create and switch to a new branch
git checkout -b type/short-descriptionExample branch names:
feature/add-message-encryptionbugfix/fix-ui-crashdocs/improve-readmetest/add-ui-tests
Branch naming conventions:
feature/- For new featuresbugfix/- For bug fixesdocs/- For documentation improvementstest/- For adding/improving testsrefactor/- For code refactoring
Make changes to the code following the project standards (see Code Standards section).
# Edit files as needed
vim confy/ui/chat.py
# See the status of changes
git statusWrite descriptive commit messages:
git commit -m "Add message signing functionality"Best practices for commit messages:
- Use the imperative mood ("add" instead of "added")
- Start with a capital letter
- Don't use a period at the end
- Limit the first line to 50 characters
- Add a more detailed description after a blank line if needed
Complete example:
Fix WebSocket connection timeout issue
- Increase default connection timeout
- Add exponential backoff retry logic
- Improve error messages
The Confy App project follows rigorous quality and style standards. Understanding these standards is essential.
The project uses Ruff for static analysis and code formatting.
Active rules:
I- Import sortingF- Pyflakes errorsE- PEP 8 style errorsW- PEP 8 style warningsPL- PylintPT- PytestD- Docstrings (Pydocstyle)UP- Syntax updatesPERF- Performance optimizations
Main configurations:
- Maximum line length: 99 characters
- Quote style: Single quotes (
') - Preview: Enabled (uses experimental Ruff features)
Use type hints in all public methods:
def update_chat_display(self, message: str) -> None:
"""Update the chat display with a new message."""
...
def get_encryption_status(self) -> bool:
"""Return the encryption status."""
...
@property
def is_connected(self) -> bool:
"""Return connection status."""
return self._connectedFollow the Google Style standard for docstrings:
def send_message(self, message: str, recipient_id: str) -> None:
"""Send an encrypted message to a recipient.
Encrypts the message using the established AES key and sends it
through the WebSocket connection.
Args:
message: The plaintext message to send.
recipient_id: The ID of the recipient.
Raises:
ValueError: If AES key is not established.
websockets.ConnectionClosed: If connection is closed.
"""
...✅ Correct:
"""Module docstring explaining the module."""
import asyncio
from typing import Final
from PySide6.QtWidgets import QMainWindow
from confy_addons import AESEncryption
from confy.settings import get_settings
from confy.core.constants import TIMEOUT
TIMEOUT: Final[int] = 30
class ChatWindow(QMainWindow):
"""Handle the main chat window."""
def __init__(self, title: str) -> None:
"""Initialize chat window.
Args:
title: The window title.
Raises:
TypeError: If title is not a string.
"""
if not isinstance(title, str):
raise TypeError('title must be str')
super().__init__()
self._title = title
def send_message(self, plaintext: str) -> None:
"""Send a message to recipient.
Args:
plaintext: The text to send.
"""
aes = AESEncryption(self._key)
encrypted = aes.encrypt(plaintext)
self._send(encrypted)❌ Incorrect:
# Missing module docstring
import asyncio
import typer
from PySide6.QtWidgets import QMainWindow # Wrong order
from confy_addons import AESEncryption
TIMEOUT = 30 # No type hint
class ChatWindow(QMainWindow):
# Missing class docstring
def __init__(self, title: str) -> None: # Missing method docstring
if not isinstance(title, str):
raise TypeError("title must be str") # Double quotes
self._title = title
def send_message(self, plaintext: str) -> None: # Missing docstring
aes = AESEncryption(self._key)
encrypted = aes.encrypt(plaintext)
self._send(encrypted)Use constants for magic values (already defined in confy/core/constants.py):
from confy.core.constants import TIMEOUT
# ✅ Correct
if elapsed_time > TIMEOUT:
self._disconnect()
# ❌ Incorrect
if elapsed_time > 30: # Magic number!
self._disconnect()The project uses several tools to ensure quality. All are automatically executed by GitHub Actions.
Check code:
poetry run ruff check .Format code automatically:
poetry run ruff format .
poetry run ruff check . --fixChecks the correctness of type hints:
poetry run mypy -p confy --ignore-missing-importsExample of detected error:
# MyPy will complain about this:
result: int = await async_function() # Type mismatchAnalyzes cyclomatic complexity:
poetry run radon cc ./confy -a -naA = average | NA = non-aggregated (shows details per function)
Checks for security issues:
poetry run bandit -r ./confyRun all quality checks before committing:
# Check code style
poetry run ruff check .
# Format code
poetry run ruff format .
# Type checking
poetry run mypy -p confy --ignore-missing-imports
# Security check
poetry run bandit -r ./confy
# Code complexity
poetry run radon cc ./confy -a -na# 1. Create and switch to feature branch
git checkout -b feature/my-feature
# 2. Make changes to the code
vim confy/ui/chat.py
# 3. Format and check code
poetry run ruff format .
poetry run ruff check . --fix
# 4. Run type checking
poetry run mypy -p confy --ignore-missing-imports
# 5. Run security checks
poetry run bandit -r ./confy
# 6. If all passes, stage and commit
git add .
git commit -m "Add new feature"
# 7. Push to your fork
git push origin feature/my-featureTest your changes manually:
# Build and install the package locally
poetry install
# Run the app
poetry run python -m confyError: Poetry not found
pip install poetry
poetry --versionError: Virtual environment not activated
poetry shell
# or use 'poetry run' before each commandError: Qt dependencies missing
poetry install --with-devBefore pushing, synchronize with the main branch:
git fetch upstream
git rebase upstream/mainIf there are conflicts, resolve them and continue:
git add .
git rebase --continuegit push origin feature/your-feature- Go to your fork on GitHub
- You will see a "Compare & pull request" suggestion
- Click and fill in the PR template
PR Template:
## 📝 Description
Brief and clear description of what was changed and why.
## 🎯 Type of Change
- [ ] Bug fix (fix that doesn't break existing functionality)
- [ ] New feature (adds functionality that doesn't break existing features)
- [ ] Breaking change (alters existing functionality)
- [ ] Documentation
- [ ] Code refactoring
## 🔍 Checklist
- [ ] I ran `poetry run ruff format .` and the code is formatted
- [ ] I ran `poetry run ruff check .` and there are no errors
- [ ] I ran `poetry run mypy -p confy` and there are no type errors
- [ ] I ran `poetry run bandit -r ./confy` and there are no security issues
- [ ] I ran `poetry run radon cc ./confy -a -na` and complexity is acceptable
- [ ] I tested the changes manually
- [ ] I updated documentation if necessary
- [ ] My PR has no conflicts with the main branch
## 🖼️ Testing (if applicable)
Describe how you tested these changes or any special testing considerations.
## 📚 References
Links to related issues or relevant documentation.
Closes #123Keep the conversation professional and constructive:
- Answer all questions from reviewers
- Make requested changes with new commits
- If you disagree, explain your viewpoint educatedly
- Ask for clarification if you don't understand
- Code follows standards - Ruff, MyPy, Bandit, Radon
- Quality checks pass - All automated tests must pass
- Documentation updated - Docstrings updated if needed
- Well-structured commits - Clear and atomic messages
- No breaking changes - Unless explicitly intended
- Submit the PR
- Automated tests run in CI/CD (GitHub Actions)
- Team members review the code
- Changes are requested (if necessary)
- You make adjustments and push new commits
- After approval, the PR is merged
- Receive feedback as a learning opportunity
- Review others' code constructively
- Use professional and courteous tone
- Focus on the code, not the person
To report a security vulnerability:
- Send an email to: confy@henriquesebastiao.com
- Include:
- Detailed description of the issue
- Steps to reproduce
- Code example if possible
- Affected version
The team will respond within 48 hours. See SECURITY.md for more details.
- Fork the repository
- Clone your fork
- Create a branch (
git checkout -b feature/my-feature) - Make changes and commits
- Push to your fork
- Create a Pull Request
Use Python 3.13 or higher for development. The project requires Python 3.13+.
git clone https://github.com/YOUR-USERNAME/app.git
cd app
poetry install
poetry shellYou need a running Confy server to test the app. You can:
- Set up the server locally
- Connect to a test server if available
- Contribute to the server project as well
Run Radon to check complexity:
poetry run radon cc ./confy -a -naRefactor if necessary. PRs with very high complexity may be rejected.
Check the Ruff documentation.
You can help by:
- Reporting bugs
- Improving documentation
- Translating documentation
- Testing the app
- Sharing ideas for features
- 🔧 Ruff Documentation
- 📚 Poetry Documentation
- 🔐 Cryptography Library
- 🎨 PySide6 Documentation
- 📡 Websockets Library
Your contribution makes this project better. If you have questions, open an issue or contact us through the email above.
Built with ❤️ by Brazilian students