Находки в опенсорсе: Python
1.06K subscribers
5 photos
348 links
Легкие задачки в опенсорсе из мира Python

Чат: @opensource_findings_chat
Download Telegram
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Improve `re_path` default parameter schema (#1439)


Currently we default to str as schema for all patterns in re_path. However, this is not the only thing we can do. We can also copy the pattern itself to the schema. Example:

re_path(r'^v(?P<version>\d+)/$', VersionController.as_view())  # schema: {type: string}

We can copy the pattern as well:

# re_path (?P<version>\d+)
- name: version
in: path
schema: {type: string, pattern: '^\d+$'}

This way users would have more info about what is expected.
See

django-modern-rest/dmr/openapi/generators/component_parsers.py

Lines 136 to 152 in 87a02f5

for current schema generation.


#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 `SlugConverter` and `PathConverter` from Django in path parameters (#1441)


Currently we only support int and uuid converters from django:

django-modern-rest/dmr/openapi/generators/component_parsers.py

Lines 36 to 41 in 87a02f5

However, there are two more that we can support:

• path, we can add {"description": "Can contain slashes"} to the schema
• slug, we can add the pattern from SlugConverter

This needs to be tested. Probably we can also change the storage API. I am not sure how currently represent in for all possible providers. Probably we can store prepared schemas for types that exist.


#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
📝 Ensure that you can include abstract controllers in `Router` (#1445)


Currently Router will say nothing if you try to include Controller with is_abstract == True into the url patterns.

I propose changing as_view logic here:

django-modern-rest/dmr/controller.py

Lines 209 to 223 in 87a02f5

.as_view() must be impossible to call on the abstract controller.
Raise EndpointMetadataError for this case.


#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 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 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
📝 Increase `DMR_MAX_CACHE_SIZE` to be `1024` (#1448)


django-modern-rest/dmr/envs.py

Line 8 in 87a02f5

I think that we defined a very small default for this value. There can be way more schemes than 256 on a big project. We want to have cache by default on them.

So, use a bigger number :)


#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Create pair of JWT tokens for the docs (#1450)


Currently we can't run examples that involve JWT auth, but we have a lot of such examples. So, we need to create a pair of JWT tokens and be able to use them in # run comments the same way we use / run examples with Token auth.

Examples:

• Auth:

 django-modern-rest/docs/examples/auth/token/revoke_token.py

 Lines 11 to 23 in 87a02f5

• django-modern-rest/docs/tools/sphinx_ext/run_examples.py

 Lines 951 to 952 in 87a02f5

Btw, also remove Token support from Query, since we don't use it anymore:

django-modern-rest/docs/tools/sphinx_ext/run_examples.py

Lines 840 to 844 in 87a02f5


#documentation #feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Support `default` values for `TypeVar` when using controller type var inference (#1452)


We have a TODO here:

django-modern-rest/dmr/types.py

Lines 318 to 326 in 405ba9b

We either need to:

1. Support the typevars with defaults, add tests, remove TODO
2. Or just add tests and remove TODO if it is already supported

#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Provide concrete views (#1457)


Currently we have a lot of reusable views for auth.
But, this is not really cool to do the manual stuff. Even if it take just several lines. Especially, when I don't need any customizations.

I propose providing new folders near the existing views/, let's call it concrete_views/ and we will put all the same views with default implementations there.

This way people can just import and use them with no manual work.

This would require a bit of integration testing :)
We would need to test default implementations the same way we test reusable views now.
And we should highlight these new views in the docs. And suggest using them over the more complex reusable ones.


#feature #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Support explicitly abstract controllers (#1458)


Currently we only infer Controller.is_abstract ourself:

django-modern-rest/dmr/controller.py

Line 206 in 405ba9b

But, there might be valid cases where people want to define controller to be reused without any customizations or with just the input / return type customizations.

We must respect top-level is_abstract controller definition. Child classes without explicit is_abstract = True must be treated as concrete if they have the serializer.

This way people can create generic controller only on some parts. This would also need a doc update in the "Reusable code" section with the example.


#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Improve testing of complex type-forms (#1460)


We test quite a lot of type forms in our tests. But, we never test code like:

type UserBody = Body[User]

class MyController(...):
def post(self, parsed_body: UserBody) -> str: ...

This must define the correct component parser for Body. The same should be tested with UserBody: TypeAlias = Body[User]

For all the serializers.

One more thing: union type with ResponseSpecMetadata.

class MyController(...):
def get(self) -> Annotated[UserModel, ResponseSpecMetadata(headers={'X-Id': HeaderSpec()})] | str: ...

I think that there can be bugs in this code, see unwrap_annotation in litestar on how we can properly unwrap all annotations and get the metadata.

Please, add tests first. Then fix bugs if present. Feel free to discuss the design if needed.


#feature #help_wanted #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 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 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 msgspec
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 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
📝 `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 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 @milssky
📝 Changes in benchmarking (#1505)


While working toward #207, I ran into the need for reliable benchmarking. We currently have four workers benchmarked using ab, which does not properly support HTTP/1.1. In particular, ab turns out to handle the -k flag incorrectly: it sends HTTP/1.0 requests with a Connection: Keep-Alive header, and different servers handle these requests differently. As a result, Uvicorn and Granian are effectively being tested under different conditions.

Furthermore, when multiple workers are used, the benchmark measures more than just the performance of the request-response lifecycle. The load generator creates a limited number of TCP connections, which the operating system distributes among the worker processes. Each keep-alive connection then remains bound to a single worker. This distribution may be uneven and can vary between runs, significantly affecting the resulting RPS.

Therefore, the current results cannot be used to evaluate the impact of individual parts of Django or a future RSGI implementation.

I see two possible approaches:

1. Fix the existing benchmark:
 • replace ab with a load generator that properly supports HTTP/1.1, such as hey;
 • run all servers with a single worker;
 • add Granian running in ASGI mode and soon add Granian in RSGO mode;
 • use the same concurrency level, duration, and other parameters for every server.
2. Keep the existing benchmark unchanged and add a separate benchmark for the request-response lifecycle:
 • use a single worker for Uvicorn, Granian, and Gunicorn;
 • use hey as the primary load generator;
 • run all servers under identical conditions;

Let’s discuss which direction we should take.


#feature #help_wanted #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 `_validate_throttling` check is a bad design :( (#1600)


This code

django-modern-rest/dmr/validation/endpoint_metadata.py

Lines 934 to 971 in 6649d05

knows a lot about specific backends for throttling. But, why do we do this in metadata validation? Why don't we create .validate method in throttling (and auth just in case) objects instead?

Like we do for parser and renderer objects:

django-modern-rest/dmr/parsers.py

Lines 47 to 58 in 6649d05

This way we can validate objects directly where they know how to self-validate.


#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 `Settings.throttling_allow_unsafe_cache` is a bad design (#1611)


After #1600 we moved the throttling validation to throttling classes.

So, there's no need for a global setting now. It must be removed and we must add allow_unsafe_cache parameter to _DjangoCache instead.


#feature #good_first_issue #help_wanted #opensource_september #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Improve `dmr` skill with `concrete_views` example (#1670)


We should state that using concrete_views is better than implementing your own views that do not change anything.

Add this to the dmr skill.


#feature #good_first_issue #help_wanted #django_modern_rest
sent via relator
🚀 New issue to wemake-services/django-modern-rest by @sobolevn
📝 Improve `dmr` skill with CSRF example (#1671)


Currently this example shows how to protect a view with CSRF:

django-modern-rest/dmr/.agents/skills/dmr/references/security.md

Lines 117 to 176 in 1cb33fb

However, there are better ways for CSRF protection, see csrf_exempt=False.
This example must show something else :)


#feature #good_first_issue #help_wanted #django_modern_rest
sent via relator