Skip to content
Merged
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
10 changes: 4 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- name: Set up Python
uses: astral-sh/setup-uv@v6
with:
python-version: 3.12

- name: Install Poetry
run: pipx install poetry
enable-cache: true

- name: Build Package
run: poetry build
run: uv build

- uses: actions/upload-artifact@v4
with:
Expand Down
29 changes: 4 additions & 25 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,19 @@ jobs:
matrix:
python-version: ["3.11", "3.12"]

services:
default-database:
image: postgres:15.5-alpine
env:
POSTGRES_HOST_AUTH_METHOD: trust
ports: ["6543:5432"]
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

task-processor-database:
image: postgres:15.5-alpine
env:
POSTGRES_HOST_AUTH_METHOD: trust
ports: ["6544:5432"]
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v4
- name: Set up Python
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
python-version: ${{ matrix.python-version }}

- name: Install Poetry
run: pipx install poetry

- name: Install Dependencies
env:
opts: --with dev
run: make install-packages

- name: Check for missing migrations
env:
opts: --no-input --dry-run --check
run: make django-make-migrations
run: make docker-up django-make-migrations

- name: Check for new typing errors
run: make typecheck
Expand Down
11 changes: 5 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ repos:
args: [--fix]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/python-poetry/poetry
rev: 2.2.1
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.7
hooks:
- id: poetry-check
- id: poetry-lock
- id: uv-lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
Expand All @@ -24,11 +23,11 @@ repos:
- id: python-typecheck
name: python-typecheck
language: system
entry: poetry run mypy .
entry: make typecheck
require_serial: true
pass_filenames: false
types: [python]

ci:
skip: [python-typecheck, poetry-lock]
skip: [python-typecheck, uv-lock]
autoupdate_commit_msg: "ci: pre-commit autoupdate"
65 changes: 34 additions & 31 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,64 @@

DOTENV_OVERRIDE_FILE ?= .env

POETRY_VERSION ?= 2.1.3

COMPOSE_FILE ?= docker/docker-compose.local.yml
COMPOSE_PROJECT_NAME ?= flagsmith-common

-include $(DOTENV_OVERRIDE_FILE)

.PHONY: install-pip
install-pip:
python -m pip install --upgrade pip
.PHONY: install-packages
install-packages: ## Install all required packages
uv sync $(or $(opts),'--all-extras')

.PHONY: install-poetry
install-poetry:
curl -sSL https://install.python-poetry.org | python3 - --version ${POETRY_VERSION}
.PHONY: install-pre-commit ## Install pre-commit hooks
install-pre-commit:
uv run pre-commit install

.PHONY: install-packages
install-packages:
poetry install $(opts)
.PHONY: ensure-dotenv
ensure-dotenv: ## Create an .env file suitable for running tests
@if [ ! -f .env ]; then cp .env-ci .env; echo ".env file created from .env-ci. Please update it with your settings."; fi

.PHONY: install
install: install-pip install-poetry install-packages
install: install-packages install-pre-commit ensure-dotenv ## Ensure the environment is set up

.PHONY: lint
lint:
poetry run pre-commit run -a
lint: ## Run linters
uv run --all-extras pre-commit run --all-files

.PHONY: docker-up
docker-up:
docker-up: ## Start Docker containers
docker compose up --force-recreate --remove-orphans -d
docker compose ps

.PHONY: docker-down
docker-down:
docker-down: ## Stop Docker containers
docker compose down

.PHONY: test
test:
poetry run pytest $(opts)
test: docker-up ## Run all tests
uv run --all-extras pytest $(opts)

.PHONY: typecheck
typecheck:
poetry run mypy .

typecheck: ## Run mypy
uv run --all-extras mypy src tests
.PHONY: django-make-migrations
django-make-migrations:
poetry run python manage.py waitfordb
poetry run python manage.py makemigrations $(opts)
django-make-migrations: ## Create new migrations based on the changes detected to your models
uv run --all-extras python manage.py waitfordb
uv run --all-extras python manage.py makemigrations $(opts)

.PHONY: django-squash-migrations
django-squash-migrations:
poetry run python manage.py waitfordb
poetry run python manage.py squashmigrations $(opts)
django-squash-migrations: ## Squash migrations for apps
uv run --all-extras python manage.py waitfordb
uv run --all-extras python manage.py squashmigrations $(opts)

.PHONY: django-migrate
django-migrate:
poetry run python manage.py waitfordb
poetry run python manage.py migrate
poetry run python manage.py createcachetable
django-migrate: ## Apply migrations to the database
uv run --all-extras python manage.py waitfordb
uv run --all-extras python manage.py migrate
uv run --all-extras python manage.py createcachetable

help:
@echo "Usage: make [target]"
@echo ""
@echo "Available targets:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
76 changes: 25 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,28 @@

Flagsmith's common library

### Development Setup
## Local development

This project uses [Poetry](https://python-poetry.org/) for dependency management and includes a Makefile to simplify common development tasks.
The project assumes the following tools installed:

#### Prerequisites
- [uv](https://github.com/astral-sh/uv)
- [GNU Make](https://www.gnu.org/software/make/)

- Python >= 3.11
- Make
To list available Makefile targets, run `make help`.

#### Installation
To set up local development environment, run `make install`.

You can set up your development environment using the provided Makefile:
To run linters, run `make lint`.

```bash
# Install everything (pip, poetry, and project dependencies)
make install
To run tests, run `make test`.

# Individual installation steps are also available
make install-pip # Upgrade pip
make install-poetry # Install Poetry
make install-packages # Install project dependencies
```

#### Development

Run linting checks using pre-commit:

```bash
make lint
```

Additional options can be passed to the `install-packages` target:

```bash
# Install with development dependencies
make install-packages opts="--with dev"

# Install with specific extras
make install-packages opts="--extras 'feature1 feature2'"
```

### Usage
## Usage

#### Installation
### Installation

1. `poetry add flagsmith-common`
1. Install all runtime packages: `uv add flagsmith-common[common-core,task-processor]`

2. `poetry add --G dev flagsmith-common[test-tools]` — this will enable the Pytest fixtures. Skipping this step will make Pytest collection fail due to missing dependencies.
2. To enable the Pytest fixtures, run `uv add --G dev flagsmith-common[test-tools]`. Skipping this step will make Pytest collection fail due to missing dependencies.

3. Make sure `"common.core"` is in the `INSTALLED_APPS` of your settings module.
This enables the `manage.py flagsmith` commands.
Expand All @@ -61,11 +35,11 @@ This enables the `route` label for Prometheus HTTP metrics.

5. To enable the `/metrics` endpoint, set the `PROMETHEUS_ENABLED` setting to `True`.

#### Test tools
### Test tools

##### Fixtures
#### Fixtures

###### `assert_metric`
##### `assert_metric`

To test your metrics using the `assert_metric` fixture:

Expand All @@ -84,44 +58,44 @@ def test_my_code__expected_metrics(assert_metric: AssertMetricFixture) -> None:
)
```

###### `saas_mode`
##### `saas_mode`

The `saas_mode` fixture makes all `common.core.utils.is_saas` calls return `True`.

###### `enterprise_mode`
##### `enterprise_mode`

The `enterprise_mode` fixture makes all `common.core.utils.is_enterprise` calls return `True`.

##### Markers
#### Markers

###### `pytest.mark.saas_mode`
##### `pytest.mark.saas_mode`

Use this mark to auto-use the `saas_mode` fixture.

###### `pytest.mark.enterprise_mode`
##### `pytest.mark.enterprise_mode`

Use this mark to auto-use the `enterprise_mode` fixture.

#### Metrics
### Metrics

Flagsmith uses Prometheus to track performance metrics.

The following default metrics are exposed:

##### Common metrics
#### Common metrics

- `flagsmith_build_info`: Has the labels `version` and `ci_commit_sha`.
- `flagsmith_http_server_request_duration_seconds`: Histogram labeled with `method`, `route`, and `response_status`.
- `flagsmith_http_server_requests_total`: Counter labeled with `method`, `route`, and `response_status`.
- `flagsmith_http_server_response_size_bytes`:Histogram labeled with `method`, `route`, and `response_status`.
- `flagsmith_http_server_response_size_bytes`: Histogram labeled with `method`, `route`, and `response_status`.
- `flagsmith_task_processor_enqueued_tasks_total`: Counter labeled with `task_identifier`.

##### Task Processor metrics
#### Task Processor metrics

- `flagsmith_task_processor_finished_tasks_total`: Counter labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).
- `flagsmith_task_processor_task_duration_seconds`: Histogram labeled with `task_identifier`, `task_type` (`"recurring"`, `"standard"`) and `result` (`"success"`, `"failure"`).

##### Guidelines
#### Guidelines

Try to come up with meaningful metrics to cover your feature with when developing it. Refer to [Prometheus best practices][1] when naming your metric and labels.

Expand Down
Loading