Skip to content

Custom python linters

See: Notion page ⧉

NoQA codes

ALN002

Checks that we don't import components in shared

ALN004

Checks that we don't import apps in shared

ALN009

Checks that models do not import business logic

ALN010

UUID foreign keys must be called as UUID(as_uuid=True)

ALN011

cache.memoize() must always have a timeout argument to make them eligible for eviction by our current redis policy"

ALN014

Checks that modification of attributes, or instantiation of policies, enrollments, employments and exemptions are only done inside the fr health insurance affiliation component only

ALN015

Checks that we don't call legacy user lifecycle functions

ALN016

logger can't use keyword arguments

ALN017

Do not use top of file imports for business_logic or services in controllers, admin_tools or models, unless for typing. See this Notion page : https://www.notion.so/alaninsurance/Imports-and-start-up-time-WIP-5495c8713847434986ef03ad09158bf1 ⧉

ALN018

Do not put python code to init files. It's executed when the module is loaded, it can generate weird side effects, and slow the loading of the application

ALN021

Foreign keys must use models, not string. See this Notion page : https://www.notion.so/alaninsurance/Imports-5495c8713847434986ef03ad09158bf1 ⧉

ALN023

Do not use top of file imports for #{nice_output}, they are slow to load and make the app starts slower

ALN024

Single health contract is deprecated: a company can have multiple contracts. Prefer using company.contracts.

ALN025

Prevents prevoyance_claim_management to import claim_management

ALN026

Prevents claim_management to import prevoyance_claim_management

ALN027

This class checks that no protected attribute access is used.

ALN030

@command_XXX must be after @XXX.command

ALN032

Checks module names

ALN034

While the shareable feature code lives in fr_api, you should consider it as a standalone feature and not as a part of Alan France. You should avoid imports from other features and other modules of apps/fr_api. See https://www.notion.so/alaninsurance/Building-shareable-features-0c4a2681e88d4b8c8e68aaaf66794e99 ⧉",

ALN036

URL or URI parameters can lead to Server Side Request Forgery (SSRF) attacks. Attackers could get the server to make requests to an unintended location, which could lead to unauthorized actions or access to data within the network. https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html ⧉

ALN037

@property are not serialized by dataclass_json. If not a problem for your use case, please ignore (# noqa: ALN037). "See this Notion page: https://www.notion.so/alaninsurance/Dataclass-the-good-parts-8f387ec2a8e24a55af294237b97dc210#a611a9154af448a38e552c61415169df ⧉

ALN038

ALN038: Calling tracer.{func_name} directly is not allowed. Please use shared.helpers.tracing.tag_current_request_root_span instead. Refer to https://www.notion.so/alaninsurance/Performance-Monitoring-APM-50bda306a47446a3912cc1eb10977335#25eb69a5452040d68f512f2cded9970b ⧉ to understand why in more details.

ALN039

The module public cannot import other components (or from apps/), it's meant to be the public interface of the component #{self.component_name}, see: https://www.notion.so/alaninsurance/Modular-monolith-a9d84f1318d34115bbd08b3648e5a587 ⧉",

ALN041

As the model '{node.name}' is in a component it must be part of specific schema that is declared in components/{self.component_name}/models/helpers.py",

ALN042

1/n or n/1 relationships must define an explicit 'order_by' clause.

ALN043

You can only import things from a Component public module, see: https://www.notion.so/alaninsurance/Modular-monolith-a9d84f1318d34115bbd08b3648e5a587 ⧉",

ALN045

HealthContract.query should not be called directly outside from the contracts_management/ module. Please check the guidelines: https://www.notion.so/alaninsurance/Contract-management-module-WIP-405f318eae714430a9e29ce40b2811bb?pvs=4#0ea62ff6f41148c5a385f7bc94a6b250 ⧉

ALN046

to use owner_only strategy the class must be wrapped with the @with_ownership decorator

ALN047

ForeignKey columns must be indexed. Please add index=True to the Column definition and make sure the migration is created

ALN049

app is a globally shared fixture with the same controllers as the production one, registering blueprints will impact other tests

ALN051

Check that we use isodate_field(), optional_isodate_field(), isodatetime_field() and optional_isodatetime_field() in json dataclasses for es/be/ca apps

ALN053

Importing a model at the top of load_all_models is not allowed as it can break the versioning manager. All imports should be made in the load_all_models method after the versioning manager call.

ALN054

Migrations should not raise exceptions. Please update raise_when_too_many_locks to False before committing

ALN055

Files containing tests should be prefixed with 'test_' or tests won't run!

ALN056

freeze_time as a function decorator isn't working well with pytest, you should convert it to a context manager

ALN057

Don't use context managers (aka with xxx) with mocker in pytest. They do not work as expected.

ALN058

import inside freeze_time context managers can break the imported module

ALN059

Checks that all component dependencies are declared in the root of a component

ALN061

invalid AWS Secrets Manager secret name - it must follow the defined naming scheme https://www.notion.so/alaninsurance/Using-AWS-Secrets-Manager-1bb472e7a620429ab362052c91b729a4?pvs=4#0e4fae3a55b74b08b3651efabcb2cc12 ⧉

ALN062

Opening and closing curly braces in strings don't match

ALN063

Don't use the @dataclass_json decorator, use the DataClassJsonMixin instead, as it provides better typing.

ALN064

Default factory fields should not contain date or datetime objects, Please use factory.LazyFunction or factory.LazyAttribute instead

ALN065

This checker is used to ensure that the decryption of medical conversation messages can only be done in the dedicated clinic_ai.py file Decided here: https://github.com/alan-eu/Topics/discussions/25049?sort=old#discussioncomment-8569509 ⧉ (item 5)

ALN066

Using strings to indicate column or relationship paths in loader options is deprecated and will be removed in SQLAlchemy 2.0. Please use the class-bound attribute directly.

ALN068

cached() must always have an expire_in argument to make them eligible for eviction by our current redis policy"

ALN069

You can't import models from other components, see: https://www.notion.so/alaninsurance/Modular-monolith-a9d84f1318d34115bbd08b3648e5a587 ⧉",

ALN070

import inside freeze_time context managers can break the imported module

ALN071

SQLAlchemy v2 migration, in models all attributes (or functions with @declared_attr) must return a Mapped[...] type. If it's a class variable type it with ClassVar[...]

ALN072

Functions decorated with @enqueueable should not use non-primitive type arguments. The function is used by RQ and the arguments must be serializable and robust for code moves/refactors.

ALN073

Don't call functions without assigning their return value to a variable.

ALN076

The tablename class attribute is mandatory on all SQLAlchemy models inheriting from DbModel, AlanNonVersionedModel, BaseModel or any of their derived classes.

ALN077

Check for usage of backref in SQLAlchemy relationships and suggest using back_populates instead.

ALN079

Check for direct instantiation of AlanBaseFactory or its derived classes. Always use the .create() class method instead of direct instantiation.

ALN080

The Model.query.get(...) method is considered legacy as of the 1.x series of SQLAlchemy and will be removed. Use " current_session.get(Model, ...) instead.

ALN081

@view_method must be before @request_argument

TODO Long term solution will be implemented in Q2

ALN083

Flake8 plugin to check ProfileService constructor usage.

ALN084

Prevents the use of Flask's current_app.config. Use shared.helpers.config.current_config instead.

ALN085

Enforces SQLAlchemy 2.0 query style by detecting deprecated patterns that will be removed in SQLAlchemy 2.0.

This linter checks for: 1. Usage of session.query() which is deprecated in favor of session.scalar(), session.scalars(), or session.execute()

Note: Other SQLAlchemy 2.0 deprecation warnings are already being turned into errors at runtime by the _turn_sql_alchemy_warning_into_errors function in backend/shared/models/orm/sqlalchemy.py.

ALN086

Enforces the use of mapped_column instead of Column in SQLAlchemy 2.0+ models.

This linter checks for usage of Column() calls which should be replaced with mapped_column().

In SQLAlchemy 2.0+, Column is deprecated in favor of mapped_column for better type annotation support and modern SQLAlchemy patterns.

Note: Migration files (in directories containing "migrations") and Column() calls inside Table() definitions are excluded from this check as they legitimately need to use Column().

ALN087

Suppress SQLAlchemy query tracker warnings for N+1 queries and unused eager loads.

This linter serves as a marker to suppress specific SQLAlchemy query optimization warnings. When the SQLAlchemy query tracker detects potential N+1 queries or unused eager loads, it will check for the presence of this linter (ALN087) at the exact line number where the issue occurs. If found, the warning will be suppressed.

ALN088

Prevents the use of unless=is_test_mode in cache decorators. This pattern changes behavior between test and production environments, which is not a best practice.

ALN089

pytest fixtures with autouse=True in conftest.py files can have unwanted side-effects as they will be used in any tests in the subfolders and can inadvertently use other fixtures that add functionality. Instead, mark tests that need the fixture explicitly with @pytest.mark.usefixtures("fixture_name") or use the fixture as a parameter.

ALN090

All modular monolith components must have an observability.py file with a ServiceObservability instance. This ensures all components are properly instrumented for observability.

ALN091

All API endpoint functions in components/*/public/ must have @obs.api_call decorator. This ensures all public API endpoints are properly instrumented for observability.