🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Parse `summary` and `description` from `Controller` for `PathItem` docs (#1446)
Currently we don't parse
django-modern-rest/dmr/controller.py
Lines 553 to 561 in 87a02f5
What we can do instead?
• Use
• If it is empty, parse
• If it is explicitly
• Test this
• Update all existing snapshots
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Parse `summary` and `description` from `Controller` for `PathItem` docs (#1446)
Currently we don't parse
summary and description from docstrings for controllers, only for endpoints. This is not good.django-modern-rest/dmr/controller.py
Lines 553 to 561 in 87a02f5
What we can do instead?
• Use
Empty as the default value for Controller.summary and Controller.description• If it is empty, parse
summary and description from the docstring, just like EndpointMetadata does• If it is explicitly
None, then do nothing• Test this
• Update all existing snapshots
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Make sure that it is possible to customize `operation_id` generation (#1461)
If people need to tailor the
I think that we need to do it somewhere here:
• django-modern-rest/dmr/openapi/core/context.py
Line 29 in 405ba9b
• django-modern-rest/dmr/openapi/core/context.py
Line 80 in 405ba9b
Probably via a callback? Other options are also fine :)
But, make sure that the default implementation will be kept.
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Make sure that it is possible to customize `operation_id` generation (#1461)
If people need to tailor the
operation_id exact look, we need to be able to provide a callback to do that.I think that we need to do it somewhere here:
• django-modern-rest/dmr/openapi/core/context.py
Line 29 in 405ba9b
• django-modern-rest/dmr/openapi/core/context.py
Line 80 in 405ba9b
Probably via a callback? Other options are also fine :)
But, make sure that the default implementation will be kept.
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Support better schema generation parameters (#1462)
Currently we don't pass quite a lot of options to both
django-modern-rest/dmr/plugins/pydantic/schema.py
Lines 27 to 30 in 405ba9b
When
The same with
django-modern-rest/dmr/plugins/msgspec/schema.py
Lines 24 to 27 in 405ba9b
Signature:
So, what we need to do:
1. Provide way to easily customize the schema generation for both
2. Both would have different API, matching the current defaults
3. Document how to customize the schema generation this way: create your own serializer, subclass schema generator, use it
4. Add tests for 2 of these cases, especially with custom
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Support better schema generation parameters (#1462)
Currently we don't pass quite a lot of options to both
pydantic and msgspec schema generation:django-modern-rest/dmr/plugins/pydantic/schema.py
Lines 27 to 30 in 405ba9b
When
pydantic defines this method as:def json_schema(
self,
*,
by_alias: bool = True,
ref_template: str = DEFAULT_REF_TEMPLATE,
union_format: Literal['any_of', 'primitive_type_array'] = 'any_of',
schema_generator: type[GenerateJsonSchema] = GenerateJsonSchema,
mode: JsonSchemaMode = 'validation',
) -> dict[str, Any]:
The same with
msgspec:django-modern-rest/dmr/plugins/msgspec/schema.py
Lines 24 to 27 in 405ba9b
Signature:
def schema(
type: Any,
*,
schema_hook: Optional[Callable[[type], dict[str, Any]]] = None,
ref_template: str = _REF_TEMPLATE,
) -> dict[str, Any]:
So, what we need to do:
1. Provide way to easily customize the schema generation for both
pydantic and msgspec2. Both would have different API, matching the current defaults
3. Document how to customize the schema generation this way: create your own serializer, subclass schema generator, use it
4. Add tests for 2 of these cases, especially with custom
schema_hook and schema_generator options#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Support missing OpenAPI 3.2 features (#1485)
#feature #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Support missing OpenAPI 3.2 features (#1485)
#feature #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 `OpenAPI.json_schema_dialect` is never set (#1486)
We must add
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 `OpenAPI.json_schema_dialect` is never set (#1486)
We must add
json_schema_dialect to OpenAPIConfig, because currently there's no way to set json_schema_dialect attribute.#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Make `ConfigMerge` class customizable (#1487)
Currently, there's no way to customize the
django-modern-rest/dmr/openapi/core/context.py
Lines 61 to 69 in f822e35
This goes against our design, where we provide all classes as
It should be:
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Make `ConfigMerge` class customizable (#1487)
Currently, there's no way to customize the
ConfigMerger class here:django-modern-rest/dmr/openapi/core/context.py
Lines 61 to 69 in f822e35
This goes against our design, where we provide all classes as
ClassVar[type[ConfigMerger]] objects.It should be:
class OpenAPIContext:
config_merger_cls: ClassVar[type[ConfigMerger]] = ConfigMerger
# then:
# self.config_merger = self.config_merger_cls(self)
#feature #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Make sure that `SecuritySchemeRegistry` can't re-register existing auth schemes (#1488)
Currently
django-modern-rest/dmr/openapi/core/registry.py
Lines 127 to 142 in f822e35
This needs to be fixed. It must raise an error, no error must pass silently.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Make sure that `SecuritySchemeRegistry` can't re-register existing auth schemes (#1488)
Currently
SecuritySchemeRegistry does not protect from registerting two auth schemes with the same name:django-modern-rest/dmr/openapi/core/registry.py
Lines 127 to 142 in f822e35
This needs to be fixed. It must raise an error, no error must pass silently.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Support custom `format` options, add more pre-defined formats (#1489)
Currently we only allow
Also, add all formats from https://spec.openapis.org/registry/format/ to
Also, please make sure that these types work correctly in
•
•
•
• Custom
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Support custom `format` options, add more pre-defined formats (#1489)
Currently we only allow
format strings that are present in OpenAPIFormat enum. Which is not correct, because format is an open str type. Users can create custom formats. See the spec: https://spec.openapis.org/oas/v3.2.0.html#data-type-formatAlso, add all formats from https://spec.openapis.org/registry/format/ to
OpenAPIFormat just for the usability.Also, please make sure that these types work correctly in
tests/test_unit/test_plugins/test_pydantic/test_pydantic_snapshots.py:•
pydantic.NameEmail•
pydantic.Base64Str•
pydantic.Base64Bytes• Custom
format with json_schema_extra={'custom-format': ...} for regular str field in pydantic#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Fix missing `Schema` attributes in `load_schema` (#1490)
In my personal opinion
Here's how a schema is loaded right now:
django-modern-rest/dmr/openapi/mappers/schema_loader.py
Lines 67 to 127 in f822e35
We never set:
But,
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Fix missing `Schema` attributes in `load_schema` (#1490)
In my personal opinion
load_schema is the ugliest part of the framework. New issues proposing better design of this feature is MASSIVELY welcome. But, before that we need to fix the existing problem.Here's how a schema is loaded right now:
django-modern-rest/dmr/openapi/mappers/schema_loader.py
Lines 67 to 127 in f822e35
We never set:
anchor, comment, ref, and schema_uri. Maybe others?But,
$ref is the most complex one here. Please, ignore it for now, we must fix our Reference | Schema handling in all places at once 😢#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Fix `Reference | Schema` conflict in our OpenAPI definitions (#1491)
Currently we mix up two different things in the code:
For example, this code:
Produces this schema:
But, we would load it as
So, what we need to do?
1. Analyze all places where
2. We must distinguish
3. We must change how our
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Fix `Reference | Schema` conflict in our OpenAPI definitions (#1491)
Currently we mix up two different things in the code:
Schema with $ref set and a Reference object with $ref set.For example, this code:
import pydantic
from pydantic.json_schema import GenerateJsonSchema
from dmr.openapi.mappers.schema_loader import load_schema
class WithDialect(GenerateJsonSchema):
def generate(self, schema, mode='validation'):
json_schema = super().generate(schema, mode=mode)
json_schema['$schema'] = self.schema_dialect
return json_schema
class Address(pydantic.BaseModel):
model_config = pydantic.ConfigDict(
json_schema_extra={'$anchor': 'address', '$comment': 'Postal address'},
)
city: str
class User(pydantic.BaseModel):
model_config = pydantic.ConfigDict(
json_schema_extra={'$comment': 'Internal note for schema readers'},
)
name: str = pydantic.Field(json_schema_extra={'$comment': 'Display name'})
address: Address = pydantic.Field(
default=Address(city='Moscow'),
description='Where the user lives',
)
raw = pydantic.TypeAdapter(User).json_schema(
ref_template='#/components/schemas/{model}',
schema_generator=WithDialect,
)
defs = raw.pop('$defs')
Produces this schema:
{
"$comment": "Internal note for schema readers",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"name": {"$comment": "Display name", "title": "Name", "type": "string"},
"address": {
"$ref": "#/components/schemas/Address",
"default": {"city": "Moscow"},
"description": "Where the user lives"
}
},
"required": ["name"], "title": "User", "type": "object"
}
But, we would load it as
Reference object in load_schema and we will loose default and description. Which are Schema object attributes.So, what we need to do?
1. Analyze all places where
Reference can't be even used based on https://spec.openapis.org/oas/v3.2.0.html We need to grep this page with | Reference Object and check that we don't have more places that can hold Reference objects2. We must distinguish
$ref in potential Schema objects and Reference objects3. We must change how our
maybe_resolve_reference works to also resolve $ref in Schema objects, where we need it. Maybe we create a new type ResolvedSchema and use it in places where we expect flat schemas, so we won't forget to call maybe_resolve_reference#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 It is possible to produce an empty `description` for `ResponseBody` (#1495)
django-modern-rest/dmr/openapi/generators/component_parsers.py
Lines 193 to 199 in f822e35
It misses
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 It is possible to produce an empty `description` for `ResponseBody` (#1495)
django-modern-rest/dmr/openapi/generators/component_parsers.py
Lines 193 to 199 in f822e35
It misses
or None part. Because we only skip None values from dumping.#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Test that nested URL patterns produce correct parameters (#1496)
We need to test a case like:
It might contain a bug: we should get two path parameters, not one.
#good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Test that nested URL patterns produce correct parameters (#1496)
We need to test a case like:
Router('tenants/<int:tenant_id>/', [path('users/<int:pk>/', MyController.as_view())])It might contain a bug: we should get two path parameters, not one.
#good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Test explicit `OpenAPIConfig.security` definition with `auth=None` per-endpoint (#1497)
Looks like we have a potential bug in how we define
Here we always return
django-modern-rest/dmr/openapi/generators/security_scheme.py
Lines 24 to 37 in f822e35
But, if per-document
Which is wrong.
This would require a test and a fix. Maybe we should look at current config's
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Test explicit `OpenAPIConfig.security` definition with `auth=None` per-endpoint (#1497)
Looks like we have a potential bug in how we define
security in OpenAPI.Here we always return
None:django-modern-rest/dmr/openapi/generators/security_scheme.py
Lines 24 to 37 in f822e35
But, if per-document
security is set, we need to return [] as the value. Otherwise, None won't be dumped by our None-ignoring dump_schema rules. And security rules per this endpoint will be inherited from the document.Which is wrong.
This would require a test and a fix. Maybe we should look at current config's
security to define the return type?#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Fix unused `security` field in `EndpointMetadata` and `_BasePayload` (#1499)
We don't use these two things:
1.
django-modern-rest/dmr/metadata.py
Lines 429 to 430 in f822e35
2. django-modern-rest/dmr/validation/payload.py
Line 44 in f822e35
However, I don't think that this is right. Users must have an option to configure this directly.
Let's create this rule:
• Any user provided
• It must be merged with explicit
It might be useful when people define some external security mechanims, for example that work on HTTP proxy level, or in other microservices.
New snapshot test is required for this change.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Fix unused `security` field in `EndpointMetadata` and `_BasePayload` (#1499)
We don't use these two things:
1.
security field documentation here:django-modern-rest/dmr/metadata.py
Lines 429 to 430 in f822e35
2. django-modern-rest/dmr/validation/payload.py
Line 44 in f822e35
However, I don't think that this is right. Users must have an option to configure this directly.
Let's create this rule:
• Any user provided
security objects must be saved to the metadata• It must be merged with explicit
auth= providersIt might be useful when people define some external security mechanims, for example that work on HTTP proxy level, or in other microservices.
New snapshot test is required for this change.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Fix `operation_id` default generation rules (#1500)
Currently it produces:
django-modern-rest/tests/test_unit/test_plugins/test_msgspec/test_msgspec_snapshots.py
Lines 61 to 81 in f822e35
It must produce:
Please, update all existing snapshots.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Fix `operation_id` default generation rules (#1500)
Currently it produces:
getAuthedandcookiescontrollerApiCookies for _AuthedAndCookiesController, seedjango-modern-rest/tests/test_unit/test_plugins/test_msgspec/test_msgspec_snapshots.py
Lines 61 to 81 in f822e35
It must produce:
getAuthedAndCookiesControllerApiCookiesPlease, update all existing snapshots.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 `CookieJWT[A]syncAuth` and `HeaderJWT[A]syncAuth` have the same security schema name (#1587)
This makes it impossible to use them together in a single endpoint / contoller together by default. Only a single
Which is not correct. We need to change the
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 `CookieJWT[A]syncAuth` and `HeaderJWT[A]syncAuth` have the same security schema name (#1587)
This makes it impossible to use them together in a single endpoint / contoller together by default. Only a single
jwt security schema / requirement will be generated.Which is not correct. We need to change the
CookieJWT[A]syncAuth one to be jwt_cookie#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @vyhuholl
📝 Seeded OpenAPI examples of `datetime` and `time` change with the current time (#1632)
What's wrong?
Found while working on #1629. With
Two runs 3 seconds apart, both with
polyfactory generates these with Faker, and Faker's defaults end at the current time:
So a schema with such fields is never the same on two runs, even though the
How it should be?
The same
Used versions
Reproduced on c35128a.
OS information
macOS 27.0
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 Seeded OpenAPI examples of `datetime` and `time` change with the current time (#1632)
What's wrong?
Found while working on #1629. With
DMR_SETTINGS = {'openapi_examples_seed': 1} and the same PYTHONHASHSEED, examples of datetime and time fields are different on every run:class _Event(msgspec.Struct):
created_at: dt.datetime
day: dt.date
at: dt.time
duration: dt.timedelta
class _EventController(Controller[MsgspecSerializer]):
def get(self) -> _Event:
raise NotImplementedError
Two runs 3 seconds apart, both with
PYTHONHASHSEED=0:02:18:43 {"created_at": "2000-10-08T03:39:12.378838", "day": "2025-09-16", "at": "18:36:00.366279", "duration": "P0D"}
02:18:46 {"created_at": "2000-10-08T03:39:16.378838", "day": "2025-09-16", "at": "18:36:03.421377", "duration": "P0D"}
polyfactory generates these with Faker, and Faker's defaults end at the current time:
datetime uses date_time_between, which ends at "now", and time uses time_object, which picks a time between 1970 and now. The seed fixes the random part, but the range moves with the clock, so the value moves too. date uses date_this_decade, which ends at today, so it changes once a day.So a schema with such fields is never the same on two runs, even though the
seed_example_factory docstring says that seeding per build "keeps a schema reproducible on its own".How it should be?
The same
openapi_examples_seed should give the same examples at any time. _ExampleFactory in dmr/openapi/mappers/example.py can override get_provider_map() and give datetime, date and time fixed bounds instead of "now".timedelta could get a range there too: its examples are always P0D now, because time_delta() without end_datetime starts and ends at "now".Used versions
django-modern-rest 0.15.0, polyfactory 3.3.0, faker 40.39.0Reproduced on c35128a.
OS information
macOS 27.0
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @Izcarmt95
📝 OpenAPI: duplicated tags when both Router(tags=...) and @modify(tags=...) set the same tag (#1656)
When an operation has a tag in
Expected:
This looks related to the change for #1299, which now propagates router metadata to included routes.
• django-modern-rest 0.15.0
• Django 5.2, Python 3.13
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
AI disclaimer: an AI assistant was used only to help write this issue.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
📝 OpenAPI: duplicated tags when both Router(tags=...) and @modify(tags=...) set the same tag (#1656)
When an operation has a tag in
@modify(tags=...) and its Router has the same tag in Router(tags=...), the generated OpenAPI operation lists the tag twice. UIs like Scalar then show every operation twice, once per tag entry.from dmr import Controller, modify
from dmr.openapi import build_schema
from dmr.plugins.pydantic import PydanticSerializer
from dmr.routing import Router, path
class UserController(Controller[PydanticSerializer]):
@modify(tags=['Users'])
def get(self) -> str:
return 'ok'
users = Router('/users', [path('/all', UserController.as_view(), name='users')], tags=['Users'])
api = Router('api')
api.include(users, namespace='users')
schema = build_schema(api)
print(schema.paths['/api/users/all'].get.tags) # ['Users', 'Users']
Expected:
['Users']. The router tags and the endpoint tags should be merged without duplicates.This looks related to the change for #1299, which now propagates router metadata to included routes.
• django-modern-rest 0.15.0
• Django 5.2, Python 3.13
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
AI disclaimer: an AI assistant was used only to help write this issue.
#bug #good_first_issue #help_wanted #openapi #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Set `security=None` for concrete login views (#1719)
We already set
#bug #good_first_issue #help_wanted #openapi #django_modern_rest
sent via relator
📝 Set `security=None` for concrete login views (#1719)
We already set
auth=None for them, but security= must also be disabled for the consistency.#bug #good_first_issue #help_wanted #openapi #django_modern_rest
sent via relator
❤1
🚀 New issue to wemake-services/django-modern-rest by @joefefs
📝 None endpoints still document a JSON null response body. (#1733)
What's wrong?
For endpoints that returns nothing, the server correctly sends an empty body, but the schema describes that response as
Anything that trusts that schema (like an SDK generator) might try to read this null body as JSON and crash.
How it should be?
The response should NOT have a content key, only a
Used versions
• django-modern-rest 0.16.0
• Django 5.2.17
• Python 3.13.12
• pydantic 2.13.5
• msgspec 0.22.0
OS information
macOS 26.3.2
#bug #good_first_issue #help_wanted #openapi #django_modern_rest
sent via relator
📝 None endpoints still document a JSON null response body. (#1733)
What's wrong?
For endpoints that returns nothing, the server correctly sends an empty body, but the schema describes that response as
application/json with a null schema.Anything that trusts that schema (like an SDK generator) might try to read this null body as JSON and crash.
How it should be?
The response should NOT have a content key, only a
{ "description": "No Content" } should suffice so that clients relying on the spec won't try to read a body that does not exist.Used versions
• django-modern-rest 0.16.0
• Django 5.2.17
• Python 3.13.12
• pydantic 2.13.5
• msgspec 0.22.0
OS information
macOS 26.3.2
#bug #good_first_issue #help_wanted #openapi #django_modern_rest
sent via relator