Skip to content
Merged

Dev #41

Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ on:
- main

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Install dependencies
run: uv sync --dev

- name: Lint with ruff
run: uv run ruff check .

test:
runs-on: ubuntu-latest
strategy:
Expand Down
104 changes: 72 additions & 32 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,89 @@
# Contributing
# Contributing to mAIcro

Thanks for your interest in contributing to **mAIcro**.
Thank you for your interest in contributing to mAIcro. This document sets the technical and cultural standards for contributions to ensure the project remains high-quality, reliable, and aligned with its core architecture.

## Ways to help
## Project Philosophy

- Report bugs (include steps to reproduce and expected vs actual behavior).
- Suggest features (include the problem you’re trying to solve and constraints).
- Improve docs (typos, examples, setup clarity).
- Send PRs (small, focused changes are easiest to review).
mAIcro is designed as a focused, high-performance RAG (Retrieval-Augmented Generation) service for organizations. Every contribution must respect these foundational principles:

If you’ve found a security issue, please follow `SECURITY.md` instead of opening a public issue.
* **Simple and Clear** We favor straightforward implementations over complex abstractions. The codebase should be navigable without deep knowledge of specialized frameworks.
* **Controlled Deployments** mAIcro is built for trusted environments (e.g., behind a Discord bot). It is not intended for use as a multi-tenant public API.
* **Performance is a Feature** Every new abstraction or feature should be evaluated for its impact on performance and operational reliability.

Start the local dev service:
## Ways to Contribute

```bash
uv sync --dev
cp .env.example .env
# Edit .env and set at least:
# LLM_PROVIDER=google
# GEMINI_API_KEY=...
# QDRANT_URL=http://localhost:6333
```
* **Bug Reports** Report verified bugs via GitHub Issues with clear reproduction steps, logs, and environment details.
* **Feature Suggestions**: Propose new capabilities that align with the project's stateless philosophy. Open an issue for discussion before implementing.
* **Documentation**: Improve clarity in READMEs, docstrings, or deployment guides.
* **Pull Requests**: Submit code changes for verified bugs or approved features.

## Common commands
## Local Development

Run tests:
mAIcro uses a single **Docker Compose** configuration for local development. We provide a **Makefile** to simplify common commands.

```bash
uv run pytest
```
### Prerequisites

* [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose/)
* **Google Gemini API Key**: Required for LLM generation.

### Setup

1. Initialize your environment:
```bash
cp .env.example .env
```

2. Set required variables in `.env`:
* `GEMINI_API_KEY`: Your Google AI Studio API key.
* `QDRANT_API_KEY`: Your Qdrant API key.
* `QDRANT_URL`: Your Qdrant URL.
* `DISCORD_BOT_TOKEN`: Your Discord bot token.
* `DISCORD_CHANNEL_ID`: Your Discord client ID.


3. Launch the development stack:
```bash
make dev
```

Start the API locally:
The API will be available at `http://localhost:8000`. Documentation and interactive API testing are provided at `http://localhost:8000/api/v1/docs`.

Hot-reloading is enabled through volume mapping, so code changes will automatically update the running service.

## Testing

We expect all logic changes to be covered by tests. All tests are run within the Docker environment to ensure accurate behavior.

```bash
uv run uvicorn main:app --reload --host 0.0.0.0 --port 8000
make test
```

## Pull requests
## Common Commands

* `make dev` - Start the project in the background with hot-reloading.
* `make test` - Run the test suite reliably inside the container.
* `make lint` - Check code style and common errors using `ruff`.
* `make format` - Automatically reformat code to match project standards.
* `make build` - Build the production Docker image locally.
* `make stop` - Stop all project containers.
* `make clean` - Reset environment (remove volumes, images, and orphans).
* `make logs` - Stream output from the application container.
* `make shell` - Open a terminal inside the running application container.

## Pull Request Process

1. **Branching**: Create a feature branch from `main` using descriptive names and send pull request to `dev` (e.g., `feature/hybrid-search`).
2. **Atomic Commits**: Ensure each commit represents a single logical change.
3. **Documentation**: Update relevant documentation if the change affects usage or architecture.
4. **Review Cycle**: All PRs require at least one maintainer review. Be prepared to iterate on feedback.


## Security

- Keep PRs focused and small when possible.
- Include tests for behavior changes and bug fixes.
- Update `README.md` / docs for user-facing changes.
- Don’t commit secrets (keep `.env` local; update `.env.example` if you add a new setting).
- Don’t commit local state directories (for example `var/` or `local_qdrant/`).
If you discover a security vulnerability, do NOT open a public issue. Follow the process outlined in [SECURITY.md](SECURITY.md) for private disclosure.

## Reporting issues
## Issue Reporting

Use GitHub Issues for bugs and feature requests.
When opening an issue:
1. Be descriptive and objective.
2. For feature requests, explain why the feature belongs in the core stateless backend rather than a client-side implementation.
8 changes: 3 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ WORKDIR /app

COPY pyproject.toml uv.lock README.md ./

RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-dev
RUN uv sync --frozen --no-install-project --no-dev

COPY src ./src

RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen
RUN uv sync --frozen

FROM python:3.12-slim

Expand All @@ -30,4 +28,4 @@ COPY src ./src

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
56 changes: 56 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.PHONY: dev build prod stop clean test lint format logs shell help

# Default target
help:
@echo "mAIcro Development CLI"
@echo "----------------------"
@echo "make dev - Start the development stack with hot-reloading"
@echo "make test - Run the test suite inside the container"
@echo "make lint - Check code style with ruff"
@echo "make format - Reformat code with ruff"
@echo "make build - Build the production Docker image"
@echo "make prod - Start the production stack"
@echo "make stop - Stop all project containers"
@echo "make clean - Reset environment (remove volumes and orphans)"
@echo "make logs - Stream logs from the application"
@echo "make shell - Open a shell inside the container"

# Start development stack
dev:
docker compose -f docker-compose.dev.yml up --build -d

# Build production image
build:
docker build -t maicro:latest .

# Start production stack
prod:
docker compose up --build -d

# Stop the project
stop:
docker compose -f docker-compose.yml -f docker-compose.dev.yml down

# Full clean reset
clean:
docker compose -f docker-compose.yml -f docker-compose.dev.yml down -v --rmi all --remove-orphans

# Run tests
test:
docker compose exec maicro /app/.venv/bin/pytest

# Lint code
lint:
docker compose exec maicro /app/.venv/bin/ruff check .

# Format code
format:
docker compose exec maicro /app/.venv/bin/ruff format .

# View logs
logs:
docker compose logs -f maicro

# Interactive shell
shell:
docker compose exec maicro /bin/bash
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

# mAIcro: Open Source Knowledge Service

Built and maintained by the **Dev Department of MicroClub**, the computer science club at **USTHB** (University of Science and Technology Houari Boumediene, Algiers).

**mAIcro** is an open-source AI service designed to centralize organizational knowledge and answer questions via RAG (Retrieval-Augmented Generation). It features a stateless architecture optimized for cloud deployment, automatic Discord integration, and production-ready performance.

## Table of Contents
Expand Down
44 changes: 44 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Security Policy

## Reporting a Vulnerability

We take the security of mAIcro seriously. If you believe you have found a security vulnerability, please report it to us as soon as possible.

**How to Report:**
- **Confidential Reporting**: Please email us at [microclubit@gmail.com](mailto:microclubit@gmail.com).
- **GitHub Security Advisory**: Alternatively, you can use the ["Report a vulnerability"](https://github.com/MicroClub-USTHB/mAIcro/security/advisories/new) button on GitHub.

Please include:
1. A description of the vulnerability.
2. Steps to reproduce the issue.
3. Potential impact.

We will acknowledge your report within 48 hours and provide a timeline for resolution.

---

## Security Best Practices for Users

To keep your mAIcro instance secure, please follow these guidelines:

### 1. Protect Your API Keys
mAIcro relies on several sensitive API keys:
- `GEMINI_API_KEY`
- `QDRANT_API_KEY`
- `DISCORD_BOT_TOKEN`

**Never commit these keys to version control.** Always use the `.env` file (which is included in `.gitignore`) or use a secure secret management service (like GitHub Secrets, AWS Secrets Manager, or HashiCorp Vault).

### 2. Least Privilege (Discord Bot)
When setting up your Discord bot, only grant the minimum required permissions:
- `View Channels`
- `Read Message History`
- `Message Content Intent` (required for RAG functionality)

Avoid granting `Administrator` or other broad permissions unless absolutely necessary for your specific use case.

### 3. Environment Isolation
Use separate API keys and Qdrant collections for development and production environments to prevent accidental data loss or exposure.

### 4. Regular Updates
Regularly pull the latest Docker image (`ghcr.io/microclub-usthb/maicro:latest`) to ensure you have the latest security patches and features.
5 changes: 3 additions & 2 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ services:
env_file:
- .env
volumes:
- ./src:/app/src # bind-mount source for hot reload
- ./src:/app/src
- ./tests:/app/tests
- ./pyproject.toml:/app/pyproject.toml
- ./uv.lock:/app/uv.lock
- /app/.venv # keep venv persistent inside container
- /app/.venv
ports:
- "8000:8000"
command: >
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ pythonpath = ["src"]
[dependency-groups]
dev = [
"pytest>=8.3.0",
"ruff>=0.9.3",
]
4 changes: 3 additions & 1 deletion src/api/error_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ async def handle_value_error(_: Request, exc: ValueError) -> JSONResponse:
@app.exception_handler(Exception)
async def handle_unexpected_error(_: Request, exc: Exception) -> JSONResponse:
logger.exception("Unhandled API exception", exc_info=exc)
return JSONResponse(status_code=500, content={"detail": f"Internal error: {exc}"})
return JSONResponse(
status_code=500, content={"detail": f"Internal error: {exc}"}
)
Loading
Loading