Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
56 changes: 56 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copilot Instructions

## Python Environment

Always activate and use the Python virtual environment when running Python commands:

- On Windows: `.venv\Scripts\activate`
- On Linux/macOS: `source .venv/bin/activate`

Use `python -m pip` instead of bare `pip` when installing packages.

## Dev Setup

Install all dependencies with:

```
python -m pip install -e ".[dev,test]"
```

## Python Version

This project requires Python 3.10 or newer.

## Project Structure

- `featuremanagement/` — Synchronous feature management code
- `featuremanagement/aio/` — Async equivalents of feature management classes
- `featuremanagement/_models/` — Data models (feature flags, variants, telemetry)
- `featuremanagement/_time_window_filter/` — Time window filter with recurrence support
- `featuremanagement/azuremonitor/` — Optional Azure Monitor telemetry integration
- `tests/` — Unit tests (sync and async)
- `samples/` — Sample applications

## Code Conventions

- All source files must include the Microsoft copyright header.
- All modules must have a module-level docstring.
- Maximum line length is 120 characters.
- Use type annotations on all functions and methods.

## Code Quality

Run these before submitting changes:

```
black featuremanagement
pylint featuremanagement
mypy featuremanagement
pytest tests
```

## Testing

- Sync tests are in `tests/test_*.py`
- Async tests use `pytest-asyncio` and are in files ending with `_async.py`
- Run tests with: `pytest tests`
5 changes: 2 additions & 3 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r dev_requirements.txt
pip install .
pip install ".[dev]"
- name: Analysing the code with pylint
run: |
pylint featuremanagement
Expand All @@ -30,7 +29,7 @@ jobs:
uses: streetsidesoftware/cspell-action@v6.8.0
- name: Test with pytest
run: |
pip install -r tests/requirements.txt
pip install ".[test]"
pytest tests --doctest-modules --cov-report=xml --cov-report=html
Comment thread
mrm9084 marked this conversation as resolved.
- name: Analysing the samples with pylint
run: |
Expand Down
6 changes: 0 additions & 6 deletions MANIFEST.in

This file was deleted.

2 changes: 1 addition & 1 deletion cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ignorePaths:
- '.*'
- 'build'
- 'docs'
- 'dev_requirements.txt'
- 'node_modules'
- '*.egg-info'
- '*.ini'
- '*.toml'
Expand Down
12 changes: 0 additions & 12 deletions dev_requirements.txt

This file was deleted.

2 changes: 2 additions & 0 deletions featuremanagement/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Feature management library for Python."""

from ._featuremanager import FeatureManager
from ._featurefilters import FeatureFilter
from ._defaultfilters import TimeWindowFilter, TargetingFilter
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_defaultfilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Built-in feature filter implementations."""

import logging
import hashlib
from datetime import datetime, timezone
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_featurefilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Base class for feature filters."""

from abc import ABC, abstractmethod
from typing import Mapping, Callable, Any, Optional

Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_featuremanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Synchronous feature manager implementation."""

import logging
from typing import cast, overload, Any, Optional, Dict, Mapping, List, Tuple
from ._defaultfilters import TimeWindowFilter, TargetingFilter
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_featuremanagerbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Base class for feature manager implementations."""

import hashlib
import logging
from abc import ABC
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Data models for feature management."""

from ._feature_flag import FeatureFlag
from ._variant import Variant
from ._evaluation_event import EvaluationEvent
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_allocation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Allocation model for feature variant assignment."""

from typing import cast, List, Optional, Mapping, Dict, Any, Union
from dataclasses import dataclass
from ._constants import DEFAULT_WHEN_ENABLED, DEFAULT_WHEN_DISABLED, USER, GROUP, PERCENTILE, SEED
Expand Down
1 change: 1 addition & 0 deletions featuremanagement/_models/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Constants used by feature management models."""

# Feature Flag
FEATURE_FLAG_ID = "id"
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_evaluation_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Evaluation event model for feature flag telemetry."""

from dataclasses import dataclass
from typing import Optional
from ._feature_flag import FeatureFlag
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_feature_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Feature flag condition models."""

from collections.abc import Mapping
from typing import Any, Dict, List
from ._constants import (
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_feature_flag.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Feature flag model."""

from typing import cast, List, Union, Optional, Mapping, Any
from ._feature_conditions import FeatureConditions
from ._allocation import Allocation
Expand Down
1 change: 1 addition & 0 deletions featuremanagement/_models/_targeting_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
"""Targeting context model for user and group targeting."""

from typing import NamedTuple, List

Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Telemetry metadata model."""

from typing import Dict
from dataclasses import dataclass, field

Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Variant model representing a feature flag variant."""

from typing import Any


Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_variant_assignment_reason.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Enum for variant assignment reasons."""

from enum import Enum


Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_models/_variant_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Variant reference model."""

from dataclasses import dataclass
from typing import Optional, Mapping, Any
from ._constants import VARIANT_REFERENCE_NAME, CONFIGURATION_VALUE, STATUS_OVERRIDE
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_time_window_filter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Time window filter with recurrence support."""

from ._recurrence_evaluator import is_match
from ._models import Recurrence, TimeWindowFilterSettings

Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/_time_window_filter/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Data models for the time window filter."""

from enum import Enum
from typing import Dict, Any, Optional, List
from datetime import datetime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Recurrence evaluation logic for the time window filter."""

from datetime import datetime, timedelta
from typing import Optional
from ._models import RecurrencePatternType, RecurrenceRangeType, TimeWindowFilterSettings, OccurrenceInfo, Recurrence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Validation logic for recurrence settings."""

from datetime import datetime, timedelta
from typing import List
from ._models import RecurrencePatternType, RecurrenceRangeType, Recurrence, RecurrencePattern, RecurrenceRange
Expand Down
1 change: 1 addition & 0 deletions featuremanagement/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Package version."""

VERSION = "2.1.0"
2 changes: 2 additions & 0 deletions featuremanagement/aio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Async feature management support."""

from ._featuremanager import FeatureManager
from ._featurefilters import FeatureFilter
from ._defaultfilters import TimeWindowFilter, TargetingFilter
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/aio/_defaultfilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Built-in async feature filter implementations."""

from typing import Mapping, Any
from ._featurefilters import FeatureFilter
from .._defaultfilters import (
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/aio/_featurefilters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Base class for async feature filters."""

from abc import ABC, abstractmethod
from typing import Mapping, Callable, Any, Optional

Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/aio/_featuremanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Async feature manager implementation."""

import inspect
import logging
from typing import cast, overload, Any, Optional, Dict, Mapping, List, Tuple
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/azuremonitor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# -------------------------------------------------------------------------
"""Azure Monitor telemetry integration for feature management."""

from ._send_telemetry import publish_telemetry, track_event, TargetingSpanProcessor

__all__ = [
Expand Down
2 changes: 2 additions & 0 deletions featuremanagement/azuremonitor/_send_telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
"""Telemetry publishing for feature evaluation events."""

import logging
import inspect
from typing import Any, Callable, Dict, Optional
Expand Down
29 changes: 1 addition & 28 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -1,31 +1,4 @@
[mypy]
python_version = 3.10
# Start off with these
warn_unused_configs = True
warn_redundant_casts = True
warn_unused_ignores = True

# Getting these passing should be easy
strict_equality = True
extra_checks = True

# Strongly recommend enabling this one as soon as you can
check_untyped_defs = True

# These shouldn't be too much additional work, but may be tricky to
# get passing if you use a lot of untyped libraries
disallow_subclassing_any = True
disallow_untyped_decorators = True
disallow_any_generics = True

# These next few are various gradations of forcing use of type annotations
disallow_untyped_calls = True
disallow_incomplete_defs = True
disallow_untyped_defs = True

# This one isn't too hard to get passing, but return on investment is lower
no_implicit_reexport = True

# This one can be tricky to get passing if you use a lot of untyped libraries
warn_return_any = True
strict = True

Loading
Loading