├── tests ├── __init__.py ├── test_di │ └── __init__.py ├── test_http │ ├── __init__.py │ ├── test_router │ │ ├── __init__.py │ │ └── helpers.py │ └── test_server │ │ ├── __init__.py │ │ ├── test_handlers │ │ ├── __init__.py │ │ ├── test_request │ │ │ ├── __init__.py │ │ │ ├── test_annotations │ │ │ │ ├── __init__.py │ │ │ │ ├── test_field_name_already_exists.py │ │ │ │ └── test_no_param_type_any_must_not_raise_err.py │ │ │ ├── test_default │ │ │ │ ├── __init__.py │ │ │ │ ├── test_default │ │ │ │ │ └── __init__.py │ │ │ │ └── test_optional │ │ │ │ │ └── __init__.py │ │ │ ├── test_param_attrs │ │ │ │ ├── __init__.py │ │ │ │ ├── test_num_attrs │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test_ge.py │ │ │ │ │ ├── test_gt.py │ │ │ │ │ ├── test_le.py │ │ │ │ │ └── test_lt.py │ │ │ │ └── test_str_attrs │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── test_min_length.py │ │ │ │ │ └── test_max_length.py │ │ │ └── test_stream_reader.py │ │ └── test_response │ │ │ ├── __init__.py │ │ │ ├── test_attrs │ │ │ └── __init__.py │ │ │ ├── test_static │ │ │ ├── __init__.py │ │ │ └── test.txt │ │ │ └── test_validation_success.py │ │ └── test_middlewares │ │ └── __init__.py ├── test_mypy │ ├── __init__.py │ ├── cases │ │ ├── __init__.py │ │ └── default │ │ │ ├── __init__.py │ │ │ ├── body │ │ │ ├── __init__.py │ │ │ ├── module.py │ │ │ ├── default_mypy_out.txt │ │ │ └── strict_mypy_out.txt │ │ │ ├── cookie │ │ │ ├── __init__.py │ │ │ └── module.py │ │ │ ├── header │ │ │ ├── __init__.py │ │ │ └── module.py │ │ │ ├── path │ │ │ ├── __init__.py │ │ │ └── module.py │ │ │ ├── query │ │ │ ├── __init__.py │ │ │ └── module.py │ │ │ └── check_type │ │ │ ├── __init__.py │ │ │ └── module.py │ ├── default_pyproject.toml │ └── strict_pyproject.toml ├── test_jsonify │ ├── __init__.py │ └── test_additional_attrs │ │ ├── __init__.py │ │ └── test_dict.py ├── test_application │ ├── __init__.py │ └── test_server_info.py └── constants.py ├── benchmarks └── __init__.py ├── rapidy ├── fields │ └── __init__.py ├── py.typed ├── routing │ ├── __init__.py │ └── http │ │ └── __init__.py ├── parameters │ └── __init__.py ├── endpoint_handlers │ ├── __init__.py │ └── http │ │ ├── __init__.py │ │ └── request │ │ └── __init__.py ├── mypy │ ├── _version.py │ └── __init__.py ├── web_request.py ├── streams.py └── constants.py ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── config.yml └── dependabot.yml ├── docs ├── examples │ ├── examples │ │ ├── projects │ │ │ └── base │ │ │ │ ├── src │ │ │ │ ├── __init__.py │ │ │ │ ├── providers.py │ │ │ │ ├── api.py │ │ │ │ ├── __main__.py │ │ │ │ └── config.py │ │ │ │ └── tests │ │ │ │ ├── __init__.py │ │ │ │ ├── test_api │ │ │ │ ├── __init__.py │ │ │ │ └── test_hello.py │ │ │ │ └── pytest.ini │ │ └── http_caching │ │ │ ├── cache_control.py │ │ │ ├── expires.py │ │ │ └── etag_and_if_none_match.py │ └── docs │ │ ├── quickstart │ │ ├── 10_runserver │ │ │ ├── run_app.sh │ │ │ ├── run_app_change_host_and_port.py │ │ │ ├── gunicorn.sh │ │ │ ├── gunicorn.py │ │ │ └── run_app.py │ │ ├── 01_func_handler.py │ │ ├── 02_func_handler_no_deco.py │ │ ├── 06_router.py │ │ ├── 04_controller_handler_no_deco.py │ │ ├── 05_middleware.py │ │ ├── 07_router_no_deco.py │ │ ├── 08_router_full_example.py │ │ └── 03_controller_handler.py │ │ ├── docs │ │ ├── server │ │ │ ├── application │ │ │ │ ├── 08_runserver │ │ │ │ │ ├── run_app.sh │ │ │ │ │ ├── run_app_change_host_and_port.py │ │ │ │ │ ├── gunicorn.sh │ │ │ │ │ ├── gunicorn.py │ │ │ │ │ └── run_app.py │ │ │ │ ├── 06_sub_app │ │ │ │ │ ├── curl.sh │ │ │ │ │ └── example.py │ │ │ │ ├── 05_http_router │ │ │ │ │ ├── curl.sh │ │ │ │ │ └── example.py │ │ │ │ ├── 04_sub_path_bad_practice.py │ │ │ │ ├── 01_simple_endpoint.py │ │ │ │ ├── di_lock_factory.py │ │ │ │ ├── 02_simple_auth_middleware.py │ │ │ │ ├── di_providers.py │ │ │ │ ├── 07_lifespan.py │ │ │ │ └── di_skip_validation.py │ │ │ ├── response │ │ │ │ ├── 03_response_import.py │ │ │ │ ├── handler_response │ │ │ │ │ ├── path.py │ │ │ │ │ ├── allow_head.py │ │ │ │ │ ├── response_by_alias │ │ │ │ │ │ ├── false.py │ │ │ │ │ │ └── true.py │ │ │ │ │ ├── response_exclude_defaults │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ └── false.py │ │ │ │ │ ├── response_charset.py │ │ │ │ │ ├── response_exclude_none │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ └── false.py │ │ │ │ │ ├── response_validate.py │ │ │ │ │ ├── response_exclude_unset │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ └── false.py │ │ │ │ │ ├── response_content_type │ │ │ │ │ │ ├── json_str.py │ │ │ │ │ │ ├── text.py │ │ │ │ │ │ └── json_dict.py │ │ │ │ │ ├── response_type.py │ │ │ │ │ ├── status_code.py │ │ │ │ │ ├── aiohttp_style_example.py │ │ │ │ │ ├── response_json_encoder.py │ │ │ │ │ ├── response_include_fields.py │ │ │ │ │ └── response_exclude_fields.py │ │ │ │ ├── 04_response_inject.py │ │ │ │ ├── 02_simple_response_example.py │ │ │ │ ├── 13_new_response_obj.py │ │ │ │ ├── 06_return_injected_response.py │ │ │ │ ├── response_object │ │ │ │ │ ├── 03_response_attrs │ │ │ │ │ │ ├── etag │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ ├── index.py │ │ │ │ │ │ │ └── advanced_example.py │ │ │ │ │ │ ├── charset │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── cookie │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ ├── delete.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── headers │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── text │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── body │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── content_type │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ ├── json_str.py │ │ │ │ │ │ │ ├── text.py │ │ │ │ │ │ │ ├── json_dict.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── last_modified │ │ │ │ │ │ │ ├── getter.py │ │ │ │ │ │ │ └── index.py │ │ │ │ │ │ ├── status │ │ │ │ │ │ │ ├── index.py │ │ │ │ │ │ │ └── setter.py │ │ │ │ │ │ ├── by_alias │ │ │ │ │ │ │ ├── false.py │ │ │ │ │ │ │ └── true.py │ │ │ │ │ │ ├── exclude_defaults │ │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ │ └── false.py │ │ │ │ │ │ ├── exclude_none │ │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ │ └── false.py │ │ │ │ │ │ ├── exclude_unset │ │ │ │ │ │ │ ├── true.py │ │ │ │ │ │ │ └── false.py │ │ │ │ │ │ ├── include.py │ │ │ │ │ │ ├── exclude.py │ │ │ │ │ │ └── json_encoder.py │ │ │ │ │ ├── 02_ignore_example.py │ │ │ │ │ └── 01_example.py │ │ │ │ ├── 11_validation_and_serialization │ │ │ │ │ ├── 01_success │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ ├── 02_example.py │ │ │ │ │ │ └── 03_example.py │ │ │ │ │ └── 02_failed │ │ │ │ │ │ ├── 01_example │ │ │ │ │ │ ├── example.py │ │ │ │ │ │ └── response.txt │ │ │ │ │ │ └── 02_example │ │ │ │ │ │ ├── example.py │ │ │ │ │ │ └── response.txt │ │ │ │ ├── 10_response_obj_pydantic.py │ │ │ │ ├── 12_none_return.py │ │ │ │ ├── 07_injected_response_not_recreated.py │ │ │ │ ├── 08_ignore_content_type.py │ │ │ │ ├── 09_ignore_injected_response.py │ │ │ │ ├── 05_response_inject_ext.py │ │ │ │ └── 01_text_response_example.txt │ │ │ ├── http_errors │ │ │ │ ├── 01_handler_raise_400 │ │ │ │ │ ├── curl__response.txt │ │ │ │ │ ├── curl.sh │ │ │ │ │ └── example.py │ │ │ │ ├── 02_handler_not_found │ │ │ │ │ ├── curl__response.txt │ │ │ │ │ ├── curl.sh │ │ │ │ │ └── example.py │ │ │ │ ├── 03_method_not_allowed │ │ │ │ │ ├── curl.sh │ │ │ │ │ ├── curl__response.txt │ │ │ │ │ └── example.py │ │ │ │ ├── 05_catch_422 │ │ │ │ │ ├── 02_example.py │ │ │ │ │ └── 01_example.py │ │ │ │ └── 04_request_validation_failure │ │ │ │ │ ├── curl.sh │ │ │ │ │ ├── curl__response.txt │ │ │ │ │ └── example.py │ │ │ ├── handlers │ │ │ │ ├── attrs │ │ │ │ │ ├── path.py │ │ │ │ │ ├── allow_head.py │ │ │ │ │ ├── response_zlib_executor_size.py │ │ │ │ │ ├── response_validate.py │ │ │ │ │ ├── response_charset.py │ │ │ │ │ ├── response_content_type │ │ │ │ │ │ ├── index.py │ │ │ │ │ │ ├── json_str.py │ │ │ │ │ │ ├── text.py │ │ │ │ │ │ └── json_dict.py │ │ │ │ │ ├── response_type.py │ │ │ │ │ ├── response_zlib_executor.py │ │ │ │ │ ├── response_exclude_fields.py │ │ │ │ │ ├── response_include_fields.py │ │ │ │ │ ├── response_json_encoder.py │ │ │ │ │ ├── response_exclude_defaults.py │ │ │ │ │ ├── response_by_alias.py │ │ │ │ │ ├── response_exclude_none.py │ │ │ │ │ └── response_exclude_unset.py │ │ │ │ ├── http_router │ │ │ │ │ ├── attrs │ │ │ │ │ │ ├── path.py │ │ │ │ │ │ ├── client_max_size.py │ │ │ │ │ │ ├── on_cleanup.py │ │ │ │ │ │ ├── on_startup.py │ │ │ │ │ │ ├── on_shutdown.py │ │ │ │ │ │ ├── route_handlers.py │ │ │ │ │ │ ├── middlewares.py │ │ │ │ │ │ └── lifespan.py │ │ │ │ │ ├── index.py │ │ │ │ │ └── sub_routes.py │ │ │ │ ├── 03_func_handler_add_method_aio_style.py │ │ │ │ ├── 05_func_handler_app_add_routes.py │ │ │ │ ├── 01_func_handler.py │ │ │ │ ├── 04_func_handler_routetable_deco.py │ │ │ │ ├── 02_func_handler_no_deco.py │ │ │ │ ├── 07_controller_handler_no_deco.py │ │ │ │ ├── 08_view_router.py │ │ │ │ ├── 12_view_add_routes.py │ │ │ │ ├── 10_view_routetabledef.py │ │ │ │ ├── 09_view_router_different_path.py │ │ │ │ ├── 11_view_routetabledef_different_path.py │ │ │ │ ├── 13_view_add_routes_different_path.py │ │ │ │ └── 06_controller_handler.py │ │ │ ├── request │ │ │ │ ├── parameters │ │ │ │ │ ├── body │ │ │ │ │ │ ├── index │ │ │ │ │ │ │ ├── 03_ignore_validation │ │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 02_json_decoder │ │ │ │ │ │ │ │ ├── 01_default_decoder.py │ │ │ │ │ │ │ │ ├── 02_default_decoder.py │ │ │ │ │ │ │ │ ├── 03_custom_decoder.py │ │ │ │ │ │ │ │ └── 04_decoder_with_params.py │ │ │ │ │ │ │ ├── 01_index.py │ │ │ │ │ │ │ └── 04_default │ │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ │ ├── json │ │ │ │ │ │ │ ├── 07_ignore_validation │ │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 03_num │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 04_literal │ │ │ │ │ │ │ │ ├── curl_false.sh │ │ │ │ │ │ │ │ ├── curl_null.sh │ │ │ │ │ │ │ │ ├── curl_true.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 05_str │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 01_obj │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 06_json_decoder │ │ │ │ │ │ │ │ ├── 01_default_decoder.py │ │ │ │ │ │ │ │ ├── 02_default_decoder.py │ │ │ │ │ │ │ │ ├── 03_custom_decoder.py │ │ │ │ │ │ │ │ └── 04_decoder_with_params.py │ │ │ │ │ │ │ ├── 02_array │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 09_extract_data │ │ │ │ │ │ │ │ ├── 02_extract_bytes │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ └── 01_handler_example.py │ │ │ │ │ │ │ │ ├── 03_extract_stream_reader │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ ├── 01_handler_example.py │ │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default.py │ │ │ │ │ │ │ │ │ └── 03_stream_reader_cant_default_text.txt │ │ │ │ │ │ │ │ └── 01_extract_raw.py │ │ │ │ │ │ │ └── 08_default │ │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ │ ├── text │ │ │ │ │ │ │ ├── 01_index │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 02_ignore_validation │ │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 04_extract_data │ │ │ │ │ │ │ │ ├── 01_extract_raw.py │ │ │ │ │ │ │ │ ├── 02_extract_bytes │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ └── 01_handler_example.py │ │ │ │ │ │ │ │ └── 03_extract_stream_reader │ │ │ │ │ │ │ │ │ ├── 01_handler_example.py │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default.py │ │ │ │ │ │ │ │ │ └── 03_stream_reader_cant_default_text.txt │ │ │ │ │ │ │ └── 03_default │ │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ │ ├── binary │ │ │ │ │ │ │ ├── 03_ignore_validation │ │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 02_extract_stream_reader.py │ │ │ │ │ │ │ ├── 05_rapidy_extract_data_binary.py │ │ │ │ │ │ │ ├── 06_rapidy_extract_data_stream_reader.py │ │ │ │ │ │ │ ├── 04_default │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default.py │ │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default_text.txt │ │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ │ │ └── 01_extract_bytes.py │ │ │ │ │ │ ├── multipart │ │ │ │ │ │ │ ├── 02_ignore_validation │ │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 01_index │ │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ │ ├── raw_example.txt │ │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 04_extract_data │ │ │ │ │ │ │ │ ├── 02_extract_bytes │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ └── 01_handler_example.py │ │ │ │ │ │ │ │ ├── 03_extract_stream_reader │ │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ │ ├── 01_handler_example.py │ │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default_text.txt │ │ │ │ │ │ │ │ │ └── 03_stream_reader_cant_default.py │ │ │ │ │ │ │ │ └── 01_extract_raw.py │ │ │ │ │ │ │ └── 03_default │ │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ │ └── x_www_form_urlencoded │ │ │ │ │ │ │ ├── 02_ignore_validation │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ │ │ ├── 01_index │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ │ ├── 04_extract_data │ │ │ │ │ │ │ ├── 02_extract_bytes │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ └── 01_handler_example.py │ │ │ │ │ │ │ ├── 03_extract_stream_reader │ │ │ │ │ │ │ │ ├── 01_handler_example.py │ │ │ │ │ │ │ │ ├── 02_rapidy_code.py │ │ │ │ │ │ │ │ ├── 03_stream_reader_cant_default.py │ │ │ │ │ │ │ │ └── 03_stream_reader_cant_default_text.txt │ │ │ │ │ │ │ └── 01_extract_raw.py │ │ │ │ │ │ │ └── 03_default │ │ │ │ │ │ │ ├── 01_default_exists.py │ │ │ │ │ │ │ └── 02_default_optional.py │ │ │ │ │ ├── cookies │ │ │ │ │ │ ├── 07_extract_raw.py │ │ │ │ │ │ ├── 06_alias.py │ │ │ │ │ │ ├── 03_default │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ ├── 03_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ ├── 05_diff_types.py │ │ │ │ │ │ ├── 01_extract │ │ │ │ │ │ │ ├── 01_cookie.py │ │ │ │ │ │ │ ├── 05_dict.py │ │ │ │ │ │ │ ├── 02_cookies.py │ │ │ │ │ │ │ ├── 03_base_model.py │ │ │ │ │ │ │ └── 04_dataclass.py │ │ │ │ │ │ ├── 04_default_factory │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ └── 02_ignore_validation │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ ├── path │ │ │ │ │ │ ├── 06_extract_raw.py │ │ │ │ │ │ ├── 01_index.py │ │ │ │ │ │ ├── 02_extract │ │ │ │ │ │ │ ├── 01_path.py │ │ │ │ │ │ │ ├── 02_paths.py │ │ │ │ │ │ │ ├── 05_dict.py │ │ │ │ │ │ │ ├── 03_base_model.py │ │ │ │ │ │ │ └── 04_dataclass.py │ │ │ │ │ │ ├── 04_diff_types.py │ │ │ │ │ │ ├── 05_alias.py │ │ │ │ │ │ └── 03_ignore_validation │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ ├── headers │ │ │ │ │ │ ├── 07_extract_raw.py │ │ │ │ │ │ ├── 06_alias.py │ │ │ │ │ │ ├── 03_default │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ ├── 03_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ ├── 05_diff_types.py │ │ │ │ │ │ ├── 01_extract │ │ │ │ │ │ │ ├── 01_header.py │ │ │ │ │ │ │ ├── 02_headers.py │ │ │ │ │ │ │ ├── 05_dict.py │ │ │ │ │ │ │ ├── 03_base_model.py │ │ │ │ │ │ │ └── 04_dataclass.py │ │ │ │ │ │ ├── 04_default_factory │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ └── 02_ignore_validation │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ ├── query │ │ │ │ │ │ ├── 07_extract_raw.py │ │ │ │ │ │ ├── 03_default │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ ├── 03_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ ├── 05_diff_types.py │ │ │ │ │ │ ├── 01_extract │ │ │ │ │ │ │ ├── 01_query_param.py │ │ │ │ │ │ │ ├── 02_query_params.py │ │ │ │ │ │ │ ├── 05_dict.py │ │ │ │ │ │ │ ├── 03_base_model.py │ │ │ │ │ │ │ └── 04_dataclass.py │ │ │ │ │ │ ├── 04_default_factory │ │ │ │ │ │ │ ├── 01_example.py │ │ │ │ │ │ │ └── 02_example.py │ │ │ │ │ │ ├── 06_alias.py │ │ │ │ │ │ └── 02_ignore_validation │ │ │ │ │ │ │ ├── 03_no_type.py │ │ │ │ │ │ │ ├── 02_any_type.py │ │ │ │ │ │ │ └── 01_validate_attr_false.py │ │ │ │ │ └── index │ │ │ │ │ │ ├── 03_data_extractor │ │ │ │ │ │ ├── 02_alias │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ └── 01_name_attr │ │ │ │ │ │ │ ├── curl.sh │ │ │ │ │ │ │ └── example.py │ │ │ │ │ │ ├── 02_parameters_import │ │ │ │ │ │ ├── 02_example.py │ │ │ │ │ │ └── 01_example.py │ │ │ │ │ │ ├── 05_param_annotation │ │ │ │ │ │ ├── 01_as_default.py │ │ │ │ │ │ └── 02_annotated.py │ │ │ │ │ │ ├── 01_index.py │ │ │ │ │ │ └── 04_validation.py │ │ │ │ ├── 03_inject_request │ │ │ │ │ ├── 02_example.py │ │ │ │ │ └── 01_example.py │ │ │ │ ├── 01_import │ │ │ │ │ ├── 01_example.py │ │ │ │ │ ├── 03_example.py │ │ │ │ │ └── 02_example.py │ │ │ │ └── 02_get_params_from_request_obj.py │ │ │ └── middlewares │ │ │ │ ├── 02_create_without_parameters.py │ │ │ │ ├── 05_response │ │ │ │ ├── 03_response_inject.py │ │ │ │ ├── 04_response_diff_types.py │ │ │ │ ├── 01_response_management.py │ │ │ │ └── 02_response_management.py │ │ │ │ ├── 04_validate.py │ │ │ │ ├── 01_simple_middleware.py │ │ │ │ └── 03_create_with_parameters.py │ │ ├── encoders │ │ │ ├── attrs │ │ │ │ ├── dumps.py │ │ │ │ ├── charset.py │ │ │ │ ├── dumps_encoder.py │ │ │ │ ├── exclude_defaults.py │ │ │ │ ├── include.py │ │ │ │ ├── exclude.py │ │ │ │ ├── by_alias.py │ │ │ │ ├── exclude_none.py │ │ │ │ └── exclude_unset.py │ │ │ └── index.py │ │ ├── lifespan │ │ │ ├── 01_on_startup │ │ │ │ ├── 01_example.py │ │ │ │ ├── 03_example.py │ │ │ │ ├── 02_example.py │ │ │ │ ├── 05_add_example.py │ │ │ │ └── 04_example.py │ │ │ ├── 03_on_cleanup │ │ │ │ ├── 01_example.py │ │ │ │ ├── 03_example.py │ │ │ │ ├── 02_example.py │ │ │ │ ├── 05_add_example.py │ │ │ │ └── 04_example.py │ │ │ ├── 02_on_shutdown │ │ │ │ ├── 01_example.py │ │ │ │ ├── 03_example.py │ │ │ │ ├── 02_example.py │ │ │ │ ├── 05_add_example.py │ │ │ │ └── 04_example.py │ │ │ └── 04_lifespan │ │ │ │ ├── 01_example.py │ │ │ │ ├── 03_add_example.py │ │ │ │ └── 02_example.py │ │ └── dependency_injection │ │ │ ├── handlers │ │ │ ├── providers.py │ │ │ ├── view.py │ │ │ ├── controller.py │ │ │ └── middleware.py │ │ │ ├── get_di_container.py │ │ │ ├── simple_ex.py │ │ │ ├── use_from_di.py │ │ │ ├── external_container.py │ │ │ └── use_from_component.py │ │ ├── index │ │ ├── curl_correct__response.txt │ │ ├── curl_incorrect__simple_server.sh │ │ ├── curl_correct__simple_server.sh │ │ ├── curl_incorrect__response.txt │ │ └── simple_server.py │ │ └── aiohttp_migration │ │ ├── 01_aiohttp_problems │ │ ├── sub_apps │ │ │ ├── aiohttp.py │ │ │ └── rapidy.py │ │ ├── request │ │ │ ├── rapidy.py │ │ │ └── aiohttp.py │ │ ├── validation │ │ │ └── rapidy.py │ │ ├── bg_tasks │ │ │ ├── aiohttp.py │ │ │ └── rapidy.py │ │ └── class_handlers │ │ │ └── rapidy.py │ │ └── 02_migration │ │ ├── partial │ │ ├── subapp │ │ │ ├── aiohttp.py │ │ │ └── rapidy.py │ │ └── minor │ │ │ ├── aiohttp.py │ │ │ └── rapidy.py │ │ └── full │ │ ├── rapidy.py │ │ └── aiohttp.py └── docs │ ├── assets │ ├── logo.png │ └── logo-teal.png │ ├── en │ ├── index.md │ └── docs │ │ └── mypy │ │ └── index.md │ ├── ru │ ├── index.md │ ├── examples │ │ └── index.md │ └── docs │ │ ├── mypy │ │ └── index.md │ │ └── server │ │ └── routing │ │ └── index.md │ └── extra.css └── CONTRIBUTORS /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/fields/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/py.typed: -------------------------------------------------------------------------------- 1 | Marker 2 | -------------------------------------------------------------------------------- /rapidy/routing/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_di/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/parameters/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/routing/http/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_jsonify/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/endpoint_handlers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_application/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/endpoint_handlers/http/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_router/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [daniil-grois] 2 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/body/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/cookie/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/header/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/path/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/query/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/src/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rapidy/endpoint_handlers/http/request/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_jsonify/test_additional_attrs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/check_type/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_middlewares/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_lines_enabled: true 2 | -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/tests/test_api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/10_runserver/run_app.sh: -------------------------------------------------------------------------------- 1 | python3 main.py -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_response/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_response/test_attrs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/08_runserver/run_app.sh: -------------------------------------------------------------------------------- 1 | python3 main.py -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_annotations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_default/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_response/test_static/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_response/test_static/test.txt: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/03_response_import.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response -------------------------------------------------------------------------------- /docs/examples/docs/index/curl_correct__response.txt: -------------------------------------------------------------------------------- 1 | < HTTP/1.1 200 OK ... {"data": "success"} -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/tests/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | asyncio_mode = auto 3 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_default/test_default/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_default/test_optional/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/01_handler_raise_400/curl__response.txt: -------------------------------------------------------------------------------- 1 | 400: Bad Request -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/02_handler_not_found/curl__response.txt: -------------------------------------------------------------------------------- 1 | 404: Not Found -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_num_attrs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_str_attrs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rAPIdy-org/rAPIdy/HEAD/docs/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/06_sub_app/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X GET http://127.0.0.1:8080/v1/get_hello -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/01_handler_raise_400/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X GET http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/03_method_not_allowed/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/03_method_not_allowed/curl__response.txt: -------------------------------------------------------------------------------- 1 | 405: Method Not Allowed -------------------------------------------------------------------------------- /docs/docs/assets/logo-teal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rAPIdy-org/rAPIdy/HEAD/docs/docs/assets/logo-teal.png -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/05_http_router/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X GET http://127.0.0.1:8080/v1/get_hello -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/10_runserver/run_app_change_host_and_port.py: -------------------------------------------------------------------------------- 1 | run_app(app, host='0.0.0.0', port=8080) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/02_handler_not_found/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST http://127.0.0.1:8080/some_api -------------------------------------------------------------------------------- /tests/test_mypy/default_pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.mypy] 2 | plugins = [ 3 | "pydantic.mypy", 4 | "rapidy.mypy" 5 | ] 6 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/08_runserver/run_app_change_host_and_port.py: -------------------------------------------------------------------------------- 1 | run_app(app, host='0.0.0.0', port=8080) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/path.py: -------------------------------------------------------------------------------- 1 | @get( 2 | '/', 3 | ) 4 | async def handler() -> str: 5 | return 'ok' 6 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/10_runserver/gunicorn.sh: -------------------------------------------------------------------------------- 1 | gunicorn main:rapidy --bind localhost:8080 --reload --worker-class aiohttp.GunicornWebWorker -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/04_sub_path_bad_practice.py: -------------------------------------------------------------------------------- 1 | @routes.get('/api/v1/get_hello') # <-- bad practice 2 | async def handler() -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/path.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import HTTPRouter 2 | 3 | router = HTTPRouter( 4 | path='/api', 5 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/dumps.py: -------------------------------------------------------------------------------- 1 | from rapidy.encoders import jsonify 2 | 3 | jsonify('text') # 'text' 4 | jsonify('text', dumps=True) # '"text"' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/08_runserver/gunicorn.sh: -------------------------------------------------------------------------------- 1 | gunicorn main:rapidy --bind localhost:8080 --reload --worker-class aiohttp.GunicornWebWorker -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/05_catch_422/02_example.py: -------------------------------------------------------------------------------- 1 | try: 2 | return await handler(request) 3 | except HTTPUnprocessableEntity: 4 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/03_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data=Body(), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/07_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data=Body(), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/allow_head.py: -------------------------------------------------------------------------------- 1 | @get( 2 | '/', 3 | allow_head=True, 4 | ) 5 | async def handler() -> str: 6 | return 'ok' 7 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/03_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/03_num/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d '"111"' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/07_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/07_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_cookies(request: Request) -> Mapping[str, str]: 2 | return request.cookies -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/06_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_path(request: Request) -> dict[str, str]: 2 | return dict(request.match_info) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/path.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get( 4 | '/', 5 | ) 6 | async def handler() -> ...: 7 | ... -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | - Contributors - 2 | ---------------- 3 | Daniil Grois 4 | Lev Zaplatin 5 | Evgeny Maximov 6 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/02_create_without_parameters.py: -------------------------------------------------------------------------------- 1 | @middleware 2 | async def hello_middleware(request: Request, call_next: CallNext) -> StreamResponse: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/01_index/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: text/plain" \ 3 | -d 'SomeString' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/07_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_headers(request: Request) -> CIMultiDictProxy[str]: 2 | return request.headers -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/07_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_query(request: Request) -> MultiDictProxy[str]: 2 | return request.rel_url.query -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/04_literal/curl_false.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d 'false' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/04_literal/curl_null.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d 'null' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/04_literal/curl_true.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d 'true' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/05_str/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d '"SomeString"' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/04_response_inject.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler(response: Response) -> ...: 5 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/01_simple_endpoint.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get('/') 4 | async def handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/04_request_validation_failure/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" -d '{"data": "d"}' -v \ 3 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/index/curl_incorrect__simple_server.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" -d '{"username": "U", "password": "m"}' -v \ 3 | http://127.0.0.1:8080/111 -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/01_on_startup/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def startup() -> None: 4 | print('startup') 5 | 6 | rapidy = Rapidy(on_startup=[startup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/03_on_cleanup/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def cleanup() -> None: 4 | print('cleanup') 5 | 6 | rapidy = Rapidy(on_cleanup=[cleanup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/03_default/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_query_param: str = QueryParam(default='SomeValue'), 4 | ) -> None: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/02_simple_response_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get('/') 4 | async def handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/13_new_response_obj.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response(status=201) -------------------------------------------------------------------------------- /docs/docs/en/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/docs/ru/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/sub_apps/aiohttp.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | 3 | v1_app = web.Application() 4 | app = web.Application() 5 | app.add_subapp('/v1', v1_app) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/02_on_shutdown/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def shutdown() -> None: 4 | print('shutdown') 5 | 6 | rapidy = Rapidy(on_shutdown=[shutdown]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/client_max_size.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import HTTPRouter 2 | 3 | router = HTTPRouter( 4 | path='/api', 5 | client_max_size=1000, 6 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/03_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data=Body(content_type=ContentType.stream), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/03_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(content_type=ContentType.stream), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/03_num/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | int_data: int = Body(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/05_str/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | string_data: str = Body(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data = Body(content_type=ContentType.text_plain), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/06_alias.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | cookie_data: CookieData = Cookies(alias='SomeName'), # <-- alias not working 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/06_alias.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | headers_data: HeadersData = Headers(alias='SomeName'), # <-- alias not working 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/03_data_extractor/02_alias/curl.sh: -------------------------------------------------------------------------------- 1 | curl -G -v -d "TestQueryParamName=123456789" http://127.0.0.1:8080 2 | # < HTTP/1.1 200 OK ... 3 | # 123456789 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/allow_head.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get( 4 | '/', 5 | allow_head=True, 6 | ) 7 | async def handler() -> ...: 8 | ... -------------------------------------------------------------------------------- /docs/examples/docs/index/curl_correct__simple_server.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" -d '{"username": "User", "password": "myAwesomePass"}' -v \ 3 | http://127.0.0.1:8080/111 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_zlib_executor_size.py: -------------------------------------------------------------------------------- 1 | @get( 2 | '/', 3 | response_zlib_executor_size=1024, 4 | ) 5 | async def handler() -> str: 6 | return 'hello, rapidy!' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/04_literal/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | bool_data: bool = Body(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data=Body(content_type=ContentType.m_part_form_data), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(content_type=ContentType.text_plain), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/03_default/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_cookie: str = Cookie(alias='Some-Cookie', default='SomeValue'), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/03_default/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_header: str = Header(alias='Some-Header', default='SomeValue'), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/03_data_extractor/01_name_attr/curl.sh: -------------------------------------------------------------------------------- 1 | curl -G -v -d "test_query_param_name=123456789" http://127.0.0.1:8080 2 | # < HTTP/1.1 200 OK ... 3 | # 123456789 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/01_index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | user_id: str = PathParam(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/06_return_injected_response.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler(response: Response) -> Response: 5 | return response -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/etag/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | etag = response.etag 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/01_on_startup/03_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_startup() -> None: 4 | print('async_startup') 5 | 6 | rapidy = Rapidy(on_startup=[async_startup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/03_on_cleanup/03_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_cleanup() -> None: 4 | print('async_cleanup') 5 | 6 | rapidy = Rapidy(on_cleanup=[async_cleanup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/05_diff_types.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | user_id: str = Cookie(alias='UserID'), 4 | cookie_data: CookieData = Cookies(), 5 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/05_diff_types.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | host: str = Header(alias='Host'), 4 | headers_data: HeadersData = Headers(), 5 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/05_diff_types.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | query: str = QueryParam(), 4 | query_params_data: QueryParamsData = QueryParams(), 5 | ) -> ...: -------------------------------------------------------------------------------- /docs/docs/ru/examples/index.md: -------------------------------------------------------------------------------- 1 | # Примеры создания приложений 2 | В данном разделе вы найдете примеры для создания ваших приложений. 3 | 4 | !!! note "" 5 | Все примеры представлены для версии `python3.12`. 6 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/02_on_shutdown/03_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_shutdown() -> None: 4 | print('async_shutdown') 5 | 6 | rapidy = Rapidy(on_shutdown=[async_shutdown]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/02_json_decoder/01_default_decoder.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | data: str = Body(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/01_obj/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d '{"username": "User", "password": "myAwesomePass"}' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/06_json_decoder/01_default_decoder.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | data: str = Body(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(content_type=ContentType.m_part_form_data), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data = Body(content_type=ContentType.x_www_form), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/01_extract/01_header.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Header 2 | 3 | @get('/') 4 | async def handler( 5 | host: str = Header(alias='Host'), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/02_extract/01_path.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | user_id: str = PathParam(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/04_diff_types.py: -------------------------------------------------------------------------------- 1 | @get('/{user_id}/{user_data}') 2 | async def handler( 3 | user_id: str = PathParam(), 4 | path_data: PathData = PathParams(), 5 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/05_alias.py: -------------------------------------------------------------------------------- 1 | @get('/{user_id}/{user_data}') 2 | async def handler( 3 | path_data: PathData = PathParams(alias='SomeName'), # <-- alias not working 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/01_extract/01_query_param.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, QueryParam 2 | 3 | @get('/') 4 | async def handler( 5 | query: str = QueryParam(), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/04_default_factory/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_query_param: str = QueryParam(default_factory=lambda: 'SomeValue'), 4 | ) -> None: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/06_alias.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | query_params_data: QueryParamsData = QueryParams(alias='SomeName'), # <-- alias not working 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/charset/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | charset = response.charset 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/cookie/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | cookies = response.cookies 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/headers/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | headers = response.headers 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_validate.py: -------------------------------------------------------------------------------- 1 | @get( 2 | '/', 3 | response_validate=False, 4 | ) 5 | async def handler() -> str: # <-- `str` will be ignored 6 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/01_index/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: multipart/form-data" \ 3 | -F username=User \ 4 | -F password=myAwesomePass \ 5 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: Any = Body(content_type=ContentType.x_www_form), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/01_extract/01_cookie.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Cookie 2 | 3 | @get('/') 4 | async def handler( 5 | user_id: str = Cookie(alias='UserID'), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/cookie/delete.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | response.del_cookie('SomeCookie') 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/sub_apps/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import HTTPRouter 3 | 4 | v1_app = HTTPRouter('/v1') 5 | rapidy = Rapidy(http_route_handlers=[v1_app]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/01_on_startup/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def startup(rapidy: Rapidy) -> None: 4 | print(f'startup, application: {app}') 5 | 6 | rapidy = Rapidy(on_startup=[startup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/01_on_startup/05_add_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def startup() -> None: 4 | print('startup') 5 | 6 | rapidy = Rapidy() 7 | rapidy.lifespan.on_startup.append(startup) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/03_on_cleanup/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def cleanup(rapidy: Rapidy) -> None: 4 | print(f'cleanup, application: {rapidy}') 5 | 6 | rapidy = Rapidy(on_cleanup=[cleanup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/03_on_cleanup/05_add_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def cleanup() -> None: 4 | print('cleanup') 5 | 6 | rapidy = Rapidy() 7 | rapidy.lifespan.on_cleanup.append(cleanup) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/03_inject_request/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get('/') 4 | async def handler( 5 | any_attr, 6 | ) -> ...: 7 | print(type(any_attr)) 8 | # web.Request -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/01_success/01_example.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler() -> int: # <-- `int` will be used to validate 3 | return '123' # success response --> `123` -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_by_alias/false.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get( 3 | '/', 4 | response_by_alias=False, 5 | ) 6 | async def handler() -> Result: 7 | return Result() # {"value": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_defaults/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get( 3 | '/', 4 | response_exclude_defaults=True, 5 | ) 6 | async def handler() -> Result: 7 | return Result() # {} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/text/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response(text='hello rapidy') 5 | body = response.text 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/02_on_shutdown/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | def shutdown(rapidy: Rapidy) -> None: 4 | print(f'shutdown, application: {rapidy}') 5 | 6 | rapidy = Rapidy(on_shutdown=[shutdown]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/02_on_shutdown/05_add_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def shutdown() -> None: 4 | print('shutdown') 5 | 6 | rapidy = Rapidy() 7 | rapidy.lifespan.on_shutdown.append(shutdown) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/04_default_factory/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_cookie: str = Cookie(alias='Some-Cookie', default_factory=lambda: 'SomeValue'), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/04_default_factory/01_example.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | some_header: str = Header(alias='Some-Header', default_factory=lambda: 'SomeValue'), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/10_response_obj_pydantic.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler( 5 | ) -> int: # <-- `int` type to validate will be ignored 6 | return Response() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_charset.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Charset 2 | 3 | @get( 4 | '/', 5 | response_charset=Charset.utf32, 6 | ) 7 | async def handler() -> ...: 8 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/body/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response(body={'hello': 'rapidy'}) 5 | body = response.body 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/content_type/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | content_type = response.content_type 6 | ... -------------------------------------------------------------------------------- /rapidy/mypy/_version.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from mypy.version import __version__ as mypy_version 4 | 5 | from rapidy.version import parse_version 6 | 7 | MYPY_VERSION_TUPLE = parse_version(mypy_version) 8 | -------------------------------------------------------------------------------- /rapidy/web_request.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from aiohttp.web_request import BaseRequest, FileField, Request 4 | 5 | __all__ = ( 6 | 'BaseRequest', 7 | 'FileField', 8 | 'Request', 9 | ) 10 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_charset.py: -------------------------------------------------------------------------------- 1 | from rapidy.enums import Charset 2 | 3 | @get( 4 | '/', 5 | response_charset=Charset.utf8, 6 | ) 7 | async def handler() -> str: 8 | return 'hello, rapidy!' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/05_response/03_response_inject.py: -------------------------------------------------------------------------------- 1 | @middleware 2 | async def hello_rapidy_middleware( 3 | request: Request, 4 | call_next: CallNext, 5 | response: Response, 6 | ) -> StreamResponse: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/03_default/03_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_query_param: Annotated[str, QueryParam()] = 'SomeValue', 6 | ) -> None: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_none/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get( 3 | '/', 4 | response_exclude_none=True, 5 | ) 6 | async def handler() -> Result: 7 | return Result() # {"someValue": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/last_modified/getter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | last_modified = response.last_modified 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/03_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: SomeBytesType = Body(validate=False, content_type=ContentType.stream), 4 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/01_index/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/x-www-form-urlencoded" \ 3 | -d "username=User&password=myAwesomePass" \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/02_parameters_import/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Header, Cookie, QueryParam, ..., Body 2 | 3 | async def handler( 4 | user_id: int = QueryParam(), 5 | ) -> ...: 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/05_param_annotation/01_as_default.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | user_id: int = PathParam(), 6 | ) -> ...: 7 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/03_default/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_query_param: Annotated[str, QueryParam(default='SomeValue')], 6 | ) -> None: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/status/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | status=201, 7 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/handlers/providers.py: -------------------------------------------------------------------------------- 1 | from rapidy.depends import provide, Provider, Scope 2 | 3 | class FooProvider(Provider): 4 | @provide(scope=Scope.REQUEST) 5 | async def c(self) -> int: 6 | return 1 -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/charset.py: -------------------------------------------------------------------------------- 1 | from rapidy.enums import Charset 2 | from rapidy.encoders import jsonify 3 | 4 | jsonify( 5 | 'data', 6 | charset=Charset.utf32, 7 | # or 8 | charset='utf32', 9 | ) 10 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/01_on_startup/04_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_startup(rapidy: Rapidy) -> None: 4 | print(f'async_startup, application: {app}') 5 | 6 | rapidy = Rapidy(on_startup=[async_startup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/02_handler_not_found/example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get 3 | 4 | @get('/') 5 | async def handler() -> ...: 6 | ... 7 | 8 | app = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/05_catch_422/01_example.py: -------------------------------------------------------------------------------- 1 | try: 2 | return await handler(request) 3 | except HTTPValidationFailure as validation_failure_error: 4 | errors = validation_failure_error.validation_errors 5 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/03_default/03_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_cookie: Annotated[str, Cookie(alias='Some-Cookie')] = 'SomeValue', 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/03_default/03_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_header: Annotated[str, Header(alias='Some-Header')] = 'SomeValue', 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/03_on_cleanup/04_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_cleanup(rapidy: Rapidy) -> None: 4 | print(f'async_cleanup, application: {rapidy}') 5 | 6 | rapidy = Rapidy(on_cleanup=[async_cleanup]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/03_default/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_cookie: Annotated[str, Cookie(alias='Some-Cookie', default='SomeValue')], 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/03_default/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_header: Annotated[str, Header(alias='Some-Header', default='SomeValue')], 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/02_parameters_import/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import Header, Cookie, QueryParam, ..., Body 2 | 3 | async def handler( 4 | user_id: int = QueryParam(), 5 | ) -> ...: 6 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/12_none_return.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler(response: Response) -> None: 5 | response.text = 'hello rapidy!' 6 | 7 | # success response --> `hello rapidy!` -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/by_alias/false.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> Response: 4 | return Response( 5 | Result(), 6 | by_alias=False, 7 | ) # {"value": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_defaults/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> Response: 4 | return Response( 5 | Result(), 6 | exclude_defaults=True, 7 | ) # {} -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/02_on_shutdown/04_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def async_shutdown(rapidy: Rapidy) -> None: 4 | print(f'async_shutdown, application: {rapidy}') 5 | 6 | rapidy = Rapidy(on_shutdown=[async_shutdown]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/on_cleanup.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import HTTPRouter 2 | 3 | async def cleanup() -> None: 4 | print('cleanup') 5 | 6 | router = HTTPRouter( 7 | path='/api', 8 | on_cleanup=[cleanup], 9 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/on_startup.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import HTTPRouter 2 | 3 | async def startup() -> None: 4 | print('startup') 5 | 6 | router = HTTPRouter( 7 | path='/api', 8 | on_startup=[startup], 9 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/02_extract_stream_reader.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/02_json_decoder/02_default_decoder.py: -------------------------------------------------------------------------------- 1 | import json 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | data: str = Body(json_decoder=json.loads), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/06_json_decoder/02_default_decoder.py: -------------------------------------------------------------------------------- 1 | import json 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | data: str = Body(json_decoder=json.loads), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/01_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_body_text(request: Request) -> Optional[str]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.text() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/01_index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam, Header 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | user_id: int = PathParam(), 6 | host: str = Header(alias='Host'), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/01_extract/02_query_params.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, QueryParam 2 | 3 | @get('/') 4 | async def handler( 5 | query: str = QueryParam(), 6 | star_rating: str = QueryParam(), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/07_injected_response_not_recreated.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler( 5 | response: Response, # <-- this response will be returned 6 | ) -> str: 7 | return 'ok' -------------------------------------------------------------------------------- /rapidy/mypy/__init__.py: -------------------------------------------------------------------------------- 1 | from typing import Type 2 | 3 | from mypy.plugin import Plugin 4 | 5 | from rapidy.mypy.plugin import RapidyPlugin 6 | 7 | 8 | def plugin(version: str) -> Type[Plugin]: # noqa: ARG001 9 | return RapidyPlugin 10 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/get_di_container.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | root_app = Rapidy() 4 | v1_app = Rapidy() 5 | root_app.add_subapp('/v1', v1_app) 6 | 7 | root_app.di_container # AsyncContainer 8 | v1_app.di_container # None -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/dumps_encoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from rapidy.encoders import jsonify 3 | 4 | def custom_encoder(obj: Any) -> str: 5 | ... 6 | 7 | jsonify( 8 | 'data', 9 | dumps_encoder=custom_encoder, 10 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/03_func_handler_add_method_aio_style.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | 3 | async def handler() -> dict[str, str]: 4 | return {'hello': 'rapidy'} 5 | 6 | rapidy = Rapidy() 7 | rapidy.router.add_post('/', handler) 8 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/05_func_handler_app_add_routes.py: -------------------------------------------------------------------------------- 1 | from rapidy import web, Rapidy 2 | 3 | async def handler() -> dict[str, str]: 4 | return {'hello': 'rapidy'} 5 | 6 | rapidy = Rapidy() 7 | rapidy.add_routes([web.post('/', handler)]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/on_shutdown.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import HTTPRouter 2 | 3 | async def shutdown() -> None: 4 | print('shutdown') 5 | 6 | router = HTTPRouter( 7 | path='/api', 8 | on_shutdown=[shutdown], 9 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/03_inject_request/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Header, Request 2 | 3 | @get('/') 4 | async def handler( 5 | host: str = Header(alias='Host'), 6 | *, 7 | request: Request, 8 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/05_rapidy_extract_data_binary.py: -------------------------------------------------------------------------------- 1 | async def extract_body_bytes(request: Request) -> Optional[bytes]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.read() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/01_extract/05_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Cookies 2 | 3 | @get('/') 4 | async def handler( 5 | cookie_data: dict[str, str] = Cookies(), 6 | ) -> ...: 7 | # {'UserID': ..., 'User-Session': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/03_data_extractor/01_name_attr/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import QueryParam 2 | 3 | async def handler( 4 | test_query_param_name: int = QueryParam(), 5 | ) -> int: 6 | return test_query_param_name -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/04_default_factory/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_query_param: Annotated[str, QueryParam(default_factory=lambda:'SomeValue')], 6 | ) -> None: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_none/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> Response: 4 | return Response( 5 | Result(), 6 | exclude_none=True, 7 | ) # {"someValue": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_content_type/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.enums import ContentType 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.text_plain, 6 | ) 7 | async def handler() -> str: 8 | return 'hello, rapidy!' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/02_array/curl.sh: -------------------------------------------------------------------------------- 1 | curl -X POST \ 2 | -H "Content-Type: application/json" \ 3 | -d '[{"username": "user1", "password": "password1"}, {"username": "user2", "password": "password2"}]' \ 4 | http://127.0.0.1:8080 -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/02_extract/02_paths.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam 2 | 3 | @get('/{user_id}/{user_data}') 4 | async def handler( 5 | user_id: str = PathParam(), 6 | user_data: str = PathParam(), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/02_failed/01_example/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get('/') 4 | async def handler() -> int: # <-- `int` will be used to validate 5 | return 'some_data' # <-- will raise err -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_validate.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get( 4 | '/', 5 | response_validate=False, 6 | ) 7 | async def handler() -> str: # <-- `str` will be ignored 8 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/headers/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | headers={'Some-Header': '123'}, 7 | ) 8 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/01_func_handler.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy(http_route_handlers=[handler]) 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_type.py: -------------------------------------------------------------------------------- 1 | @get( 2 | '/', 3 | response_type=dict[str, str], # <-- `dict[str, str]` will be used for validation 4 | ) 5 | async def handler() -> str: # <-- `str` will be ignored 6 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/06_rapidy_extract_data_stream_reader.py: -------------------------------------------------------------------------------- 1 | async def extract_body_stream(request: Request) -> Optional[StreamReader]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return request.content -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/01_extract/02_headers.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Header 2 | 3 | @get('/') 4 | async def handler( 5 | host: str = Header(alias='Host'), 6 | keep_alive: str = Header(alias='Keep-Alive'), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/01_extract/05_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, QueryParams 2 | 3 | @get('/') 4 | async def handler( 5 | query_params_data: dict[str, str] = QueryParams(), 6 | ) -> ...: 7 | # {'query': ..., 'star_rating': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/01_func_handler.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy(http_route_handlers=[handler]) 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_content_type/json_str.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | content_type=ContentType.json, 6 | ) 7 | async def handler() -> str: 8 | return 'hello rapidy!' # "'hello rapidy!'" -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/02_extract_bytes/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_bytes(request: Request) -> Optional[bytes]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.read() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/02_extract_bytes/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_bytes(request: Request) -> Optional[bytes]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.read() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/01_extract/02_cookies.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Cookie 2 | 3 | @get('/') 4 | async def handler( 5 | user_id: str = Cookie(alias='UserID'), 6 | user_session: str = Cookie(alias='UserSession'), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/04_default_factory/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_cookie: Annotated[str, Cookie(alias='Some-Cookie', default_factory=lambda:'SomeValue')], 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/04_default_factory/02_example.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | @get('/') 4 | async def handler( 5 | some_header: Annotated[str, Header(alias='Some-Header', default_factory=lambda:'SomeValue')], 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_unset/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get( 3 | '/', 4 | response_exclude_unset=True, 5 | ) 6 | async def handler() -> Result: 7 | return Result(someAnotherValue='new_data') # {"someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_content_type/text.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | content_type=ContentType.text_any, 6 | ) 7 | async def handler() -> str: 8 | return 'hello rapidy!' # "hello rapidy!" 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/03_method_not_allowed/example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get 3 | 4 | 5 | @get('/') 6 | async def handler() -> str: 7 | return 'ok' 8 | 9 | 10 | rapidy = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/02_extract_bytes/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_bytes(request: Request) -> Optional[bytes]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.read() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/03_data_extractor/02_alias/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import QueryParam 2 | 3 | async def handler( 4 | test_query_param_name: int = QueryParam(alias='TestQueryParamName'), 5 | ) -> int: 6 | return test_query_param_name -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/02_extract/05_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParams 2 | 3 | @get('/{user_id}/{user_data}') 4 | async def handler( 5 | path_data: dict[str, str] = PathParams(), 6 | ) -> ...: 7 | # {'user_id': ..., 'user_data': ...} -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/03_extract_stream_reader/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_stream(request: Request) -> Optional[StreamReader]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return request.content -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/03_extract_stream_reader/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: StreamReader = Body(content_type=ContentType.text_plain), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/03_extract_stream_reader/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_stream(request: Request) -> Optional[StreamReader]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return request.content -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/05_param_annotation/02_annotated.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | from rapidy.http import get, PathParam 3 | 4 | @get('/{user_id}') 5 | async def handler( 6 | user_id: Annotated[int, PathParam()], 7 | ) -> ...: 8 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/08_ignore_content_type.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType, Response 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.json, # <-- will be ignored 6 | ) 7 | async def handler() -> Response: 8 | return Response(...) -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/10_runserver/gunicorn.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy() 9 | rapidy.add_http_router(handler) 10 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/request/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get 3 | 4 | @get('/hello') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/01_handler_raise_400/example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get, HTTPBadRequest 3 | 4 | @get('/') 5 | async def handler() -> None: 6 | raise HTTPBadRequest() # 400 7 | 8 | app = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/03_extract_stream_reader/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/03_extract_stream_reader/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_stream(request: Request) -> Optional[StreamReader]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return request.content -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/body/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import Body 2 | 3 | 4 | def handler( 5 | _1: int = Body('1'), 6 | _2: int = Body(default_factory=lambda: '1'), 7 | _3: int = Body('1', default_factory=lambda: '1'), 8 | ) -> None: 9 | pass 10 | -------------------------------------------------------------------------------- /docs/docs/extra.css: -------------------------------------------------------------------------------- 1 | .base-color { 2 | color: #986be3; 3 | } 4 | 5 | .success-color { 6 | color: #00bbbb; 7 | } 8 | 9 | .warning-color { 10 | color: #f58080; 11 | } 12 | 13 | .note-color { 14 | color: #ce4c87; 15 | } 16 | 17 | .green-color { 18 | color: #00c500; 19 | } 20 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/04_default/03_stream_reader_cant_default.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(default='SomeDefault'), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/02_extract_bytes/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_bytes(request: Request) -> Optional[bytes]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.read() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/02_ignore_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType, Response 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.json, # <-- will be ignored 6 | ) 7 | async def handler() -> Response: 8 | return Response(...) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/08_runserver/gunicorn.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy() 9 | rapidy.add_http_router(handler) 10 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_content_type/json_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | content_type=ContentType.json, 6 | ) 7 | async def handler() -> dict[str, str]: 8 | return {'hello': 'rapidy!'} # {"hello": "rapidy!"} 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/01_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_post_data(request: Request) -> Optional[MultiDictProxy[Union[str, bytes, FileField]]]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.post() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_content_type/json_str.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.json, 6 | ) 7 | async def handler() -> str: 8 | return 'hello rapidy!' # "'hello rapidy!'" 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_content_type/text.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.text_any, 6 | ) 7 | async def handler() -> str: 8 | return 'hello rapidy!' # "hello rapidy!" 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_unset/true.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> Response: 4 | return Response( 5 | Result(someAnotherValue='new_data'), 6 | exclude_unset=True, 7 | ) # {"someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/03_extract_stream_reader/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: StreamReader = Body(content_type=ContentType.x_www_form), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/03_extract_stream_reader/02_rapidy_code.py: -------------------------------------------------------------------------------- 1 | async def extract_body_stream(request: Request) -> Optional[StreamReader]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return request.content -------------------------------------------------------------------------------- /tests/constants.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from typing import Final, Type 3 | 4 | DEFAULT_RETURN_TYPE: Type[str] = str 5 | DEFAULT_RETURN_VALUE: Final[str] = 'test' 6 | 7 | 8 | class ClientBodyExtractMethod(str, Enum): 9 | text = 'text' 10 | read = 'read' 11 | json = 'json' 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/04_func_handler_routetable_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import web, Rapidy 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.post('/') 6 | async def handler() -> dict[str, str]: 7 | return {'hello': 'rapidy'} 8 | 9 | rapidy = Rapidy() 10 | rapidy.add_routes(routes) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_zlib_executor.py: -------------------------------------------------------------------------------- 1 | from concurrent.futures import Executor 2 | 3 | class SomeExecutor(Executor): 4 | ... 5 | 6 | @get( 7 | '/', 8 | response_zlib_executor=SomeExecutor, 9 | ) 10 | async def handler() -> str: 11 | return 'hello, rapidy!' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/01_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_post_data(request: Request) -> Optional[MultiDictProxy[Union[str, bytes, FileField]]]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.post() -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: StreamReader = Body(content_type=ContentType.x_www_form), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/01_extract_raw.py: -------------------------------------------------------------------------------- 1 | async def extract_body_json(request: Request, body_field_info: Body) -> Optional[DictStrAny]: 2 | if not request.body_exists: 3 | return None 4 | 5 | return await request.json(loads=body_field_info.json_decoder) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/03_extract_stream_reader/03_stream_reader_cant_default.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(default='SomeDefault'), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: StreamReader = Body(default='SomeDefault', content_type=ContentType.text_plain), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_content_type/json_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, ContentType 2 | 3 | @get( 4 | '/', 5 | response_content_type=ContentType.json, 6 | ) 7 | async def handler() -> dict[str, str]: 8 | return {'hello': 'rapidy!'} # {"hello": "rapidy!"} 9 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/02_func_handler_no_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | async def handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} 6 | 7 | rapidy = Rapidy( 8 | http_route_handlers=[ 9 | post.reg('/', handler), 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/exclude_defaults.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | jsonify( 8 | Result(), 9 | response_exclude_defaults=True, 10 | ) 11 | # {} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/route_handlers.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, HTTPRouter 2 | 3 | @get('/hello') # /api/hello 4 | async def hello_handler() -> str: 5 | return 'hello rapidy!' 6 | 7 | router = HTTPRouter( 8 | path='/api', 9 | route_handlers=[hello_handler], 10 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/01_index.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class UserData(BaseModel): 5 | username: str 6 | password: str 7 | 8 | @post('/') 9 | async def handler( 10 | user_data: UserData = Body(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/03_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler_1( 3 | user_id=PathParam() 4 | ) -> ...: 5 | # ... 6 | 7 | @get('/') 8 | async def handler_2( 9 | path_data=PathParams() 10 | ) -> ...: 11 | # {'user_id': ..., 'user_data': ...} -------------------------------------------------------------------------------- /rapidy/streams.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | from aiohttp.streams import DataQueue, EMPTY_PAYLOAD, EofStream, FlowControlDataQueue, StreamReader 4 | 5 | __all__ = ( 6 | 'EMPTY_PAYLOAD', 7 | 'EofStream', 8 | 'StreamReader', 9 | 'DataQueue', 10 | 'FlowControlDataQueue', 11 | ) 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/02_func_handler_no_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post 3 | 4 | async def handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} 6 | 7 | rapidy = Rapidy( 8 | http_route_handlers=[ 9 | post.reg('/', handler), 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/04_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: bytes = Body(b'some_bytes', content_type=ContentType.stream), 4 | # or 5 | data: bytes = Body(default_factory=lambda: b'some_bytes', content_type=ContentType.stream), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/02_failed/02_example/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | data: str = Field(max_length=10) 5 | 6 | @post('/') 7 | async def handler() -> Result: 8 | return {'data': 'another_data'} # <-- will raise err -------------------------------------------------------------------------------- /tests/test_http/test_router/helpers.py: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | import pytest 4 | 5 | PATH_1: Final[str] = '/foo1' 6 | PATH_2: Final[str] = '/foo2' 7 | 8 | parametrize_method_names = pytest.mark.parametrize( 9 | 'method_name', 10 | ('get', 'post', 'put', 'patch', 'delete', 'head', 'options'), 11 | ) 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/03_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body(validate=False), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/02_array/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class UserData(BaseModel): 5 | username: str 6 | password: str 7 | 8 | @post('/') 9 | async def handler( 10 | users: list[UserData] = Body(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/07_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body(validate=False), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/02_extract_bytes/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: bytes = Body(), 6 | # also you can use pydantic validation 7 | user_data: bytes = Body(min_length=1), 8 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/01_extract/05_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Headers 2 | 3 | @get('/') 4 | async def handler( 5 | headers_data: dict[str, str] = Headers(), 6 | ) -> ...: 7 | # {Host': '0.0.0.0:8080', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', 'User-Agent': '...'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/content_type/json_str.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response, ContentType 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | body='hello rapidy!', 7 | content_type=ContentType.json, 8 | ) # "'hello rapidy!'" -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/content_type/text.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response, ContentType 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | text='hello rapidy!', 7 | content_type=ContentType.text_any, 8 | ) # "hello rapidy!" -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler_1( 3 | user_id=Cookie(alias='UserID') 4 | ) -> ...: 5 | # ... 6 | 7 | @get('/') 8 | async def handler_2( 9 | cookie_data=Cookies() 10 | ) -> ...: 11 | # # {'UserID': ..., 'User-Session': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/status/setter.py: -------------------------------------------------------------------------------- 1 | ... 2 | @get('/') 3 | async def handler() -> ...: 4 | response = Response() 5 | response.set_status(200) 6 | ... 7 | 8 | @get('/') 9 | async def handler(response: Response) -> ...: 10 | response.set_status(200) 11 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/04_default/03_stream_reader_cant_default_text.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Handler attribute with Type `Body` cannot have a default value. 3 | 4 | Handler path: `/main.py` 5 | Handler name: `handler` 6 | Attribute name: `data` 7 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/06_json_decoder/03_custom_decoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from rapidy.http import post, Body 3 | 4 | def custom_json_decoder(data: str) -> ...: 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: Any = Body(json_decoder=custom_json_decoder), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/02_json_decoder/03_custom_decoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from rapidy.http import post, Body 3 | 4 | def custom_json_decoder(data: str) -> ...: 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: Any = Body(json_decoder=custom_json_decoder), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/03_extract_stream_reader/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body, ContentType 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(content_type=ContentType.m_part_form_data), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler_1( 3 | query=QueryParam(), 4 | ) -> ...: 5 | # ... 6 | 7 | @get('/') 8 | async def handler_2( 9 | query_params_data=QueryParams(), 10 | ) -> ...: 11 | # -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/01_success/02_example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | data: str = Field(max_length=10) 5 | 6 | @post('/') 7 | async def handler() -> Result: 8 | return Result(data='some_data') # success response --> `{"data": "some_data"}` -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/01_success/03_example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | data: str = Field(max_length=10) 5 | 6 | @post('/') 7 | async def handler() -> Result: 8 | return {'data': 'some_data'} # # success response --> `{"data": "some_data"}` -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/content_type/json_dict.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response, ContentType 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | body={'hello': 'rapidy!'}, 7 | content_type=ContentType.json, 8 | ) # {"hello": "rapidy!"} 9 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_type.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | 3 | @get( 4 | '/', 5 | # `dict[str, str]` will be used for validate and serialize body response data 6 | response_type=dict[str, str], 7 | ) 8 | async def handler() -> str: # <-- `str` will be ignored 9 | return {'hello': 'rapidy'} -------------------------------------------------------------------------------- /docs/examples/examples/http_caching/cache_control.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get, HeaderName 2 | 3 | @get('/') 4 | async def handler(response: Response) -> str: 5 | content = 'success' # <-- endpoint dynamic content 6 | 7 | response.headers[HeaderName.cache_control] = "public, max-age=600, must-revalidate" 8 | 9 | return content -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/02_extract_bytes/01_handler_example.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | user_data: bytes = Body(content_type=ContentType.text_plain), 4 | # also you can use pydantic validation 5 | user_data: bytes = Body(content_type=ContentType.text_plain, min_length=1), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | body={'hello': 'rapidy'}, 7 | status=200, 8 | headers={'Some-Header': 'SomeData'}, 9 | content_type='application/json', 10 | ) -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/10_runserver/run_app.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy, run_app 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy() 9 | rapidy.add_http_router(handler) 10 | 11 | if __name__ == '__main__': 12 | run_app(rapidy) 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/02_extract/03_base_model.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import get, PathParams 3 | 4 | class PathData(BaseModel): 5 | user_id: str 6 | user_data: str 7 | 8 | @get('/{user_id}/{user_data}') 9 | async def handler( 10 | path_data: PathData = PathParams(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/docs/en/docs/mypy/index.md: -------------------------------------------------------------------------------- 1 | # mypy 2 | ## Description 3 | `Rapidy` supports its own `mypy` plugin. 4 | 5 | To enable the `mypy` plugin, simply add it to one of the configuration files. 6 | 7 | ```python 8 | # pyproject.toml 9 | [tool.mypy] 10 | plugins = [ 11 | "pydantic.mypy", 12 | "rapidy.mypy" # <-- enable rapidy plugin 13 | ] 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/request/aiohttp.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | 3 | router = web.RouteTableDef() 4 | 5 | @router.get('/hello') 6 | async def hello(request: web.Request) -> web.Response: # `request` required 7 | return web.json_response({'hello': 'aiohttp'}) 8 | 9 | app = web.Application() 10 | app.add_routes(router) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/08_runserver/run_app.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy, run_app 2 | from rapidy.http import post 3 | 4 | @post('/') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | rapidy = Rapidy() 9 | rapidy.add_http_router(handler) 10 | 11 | if __name__ == '__main__': 12 | run_app(rapidy) 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/09_extract_data/03_extract_stream_reader/03_stream_reader_cant_default_text.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Handler attribute with Type `Body` cannot have a default value. 3 | 4 | Handler path: `/main.py` 5 | Handler name: `handler` 6 | Attribute name: `data` 7 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default_text.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Handler attribute with Type `Body` cannot have a default value. 3 | 4 | Handler path: `/main.py` 5 | Handler name: `handler` 6 | Attribute name: `data` 7 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/01_extract/03_base_model.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import get, QueryParams 3 | 4 | class QueryParamsData(BaseModel): 5 | query: str 6 | star_rating: str 7 | 8 | @get('/') 9 | async def handler( 10 | query_params_data: QueryParamsData = QueryParams(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/status_code.py: -------------------------------------------------------------------------------- 1 | from http import HTTPStatus 2 | from rapidy.http import get 3 | 4 | @get( 5 | '/', 6 | status_code=201, 7 | ) 8 | async def handler() -> ...: 9 | ... 10 | 11 | @get( 12 | '/', 13 | status_code=HTTPStatus.CREATED, 14 | ) 15 | async def handler() -> ...: 16 | ... 17 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default_text.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Handler attribute with Type `Body` cannot have a default value. 3 | 4 | Handler path: `/main.py` 5 | Handler name: `handler` 6 | Attribute name: `data` 7 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/02_extract/04_dataclass.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from rapidy.http import get, PathParams 3 | 4 | @dataclass 5 | class PathData: 6 | user_id: str 7 | user_data: str 8 | 9 | @get('/{user_id}/{user_data}') 10 | async def handler( 11 | path_data: PathData = PathParams(), 12 | ) -> ...: -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_response/test_validation_success.py: -------------------------------------------------------------------------------- 1 | from aiohttp.pytest_plugin import AiohttpClient 2 | 3 | from tests.app_checkers import check_handlers_all_response_models 4 | 5 | 6 | async def test_validation_success(aiohttp_client: AiohttpClient) -> None: 7 | await check_handlers_all_response_models(aiohttp_client=aiohttp_client) 8 | -------------------------------------------------------------------------------- /docs/docs/ru/docs/mypy/index.md: -------------------------------------------------------------------------------- 1 | # mypy 2 | ## Описание 3 | `Rapidy` поддерживает собственный `mypy` плагин. 4 | 5 | Чтобы включить `mypy` плагин просто добавьте его в один из файлов конфигурации. 6 | 7 | ```python 8 | # pyproject.toml 9 | [tool.mypy] 10 | plugins = [ 11 | "pydantic.mypy", 12 | "rapidy.mypy" # <-- enable rapidy plugin 13 | ] 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/06_sub_app/example.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.get('/get_hello') 6 | async def handler() -> dict[str, str]: 7 | return {'hello': 'rapidy'} 8 | 9 | v1_app = web.Application() 10 | v1_app.add_routes(routes) 11 | 12 | app = web.Application() 13 | app.add_subapp('/v1', v1_app) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/05_response/04_response_diff_types.py: -------------------------------------------------------------------------------- 1 | @middleware 2 | async def my_middleware( 3 | request: Request, 4 | call_next: CallNext, 5 | ) -> int | str | StreamResponse: # or Union[int, str, StreamResponse] 6 | if ...: 7 | return 1 8 | elif ...: 9 | return 'string' 10 | return await call_next(request) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/04_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | data: bytes | None = Body(content_type=ContentType.stream), 4 | # or 5 | data: Optional[bytes] = Body(content_type=ContentType.stream), 6 | # or 7 | data: Union[bytes, None] = Body(content_type=ContentType.stream), 8 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class DataEnum(Enum): 5 | test = 'test' 6 | 7 | @post('/') 8 | async def handler( 9 | data: DataEnum = Body(validate=False, content_type=ContentType.text_plain), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/02_extract_bytes/01_handler_example.py: -------------------------------------------------------------------------------- 1 | @post('/') 2 | async def handler( 3 | user_data: bytes = Body(content_type=ContentType.x_www_form), 4 | # also you can use pydantic validation 5 | user_data: bytes = Body(content_type=ContentType.x_www_form, min_length=1), 6 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/01_extract/04_dataclass.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from rapidy.http import get, QueryParams 3 | 4 | @dataclass 5 | class QueryParamsData: 6 | query: str 7 | star_rating: str 8 | 9 | @get('/') 10 | async def handler( 11 | query_params_data: QueryParamsData = QueryParams(), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/validation/rapidy.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import get, Body 3 | 4 | class UserData(BaseModel): 5 | name: str 6 | age: int 7 | 8 | @get('/user') 9 | async def handler(data: UserData = Body()) -> dict[str, str]: 10 | return {'message': f'User {data.name}, {data.age} years old'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default.py: -------------------------------------------------------------------------------- 1 | from rapidy import StreamReader 2 | from rapidy.http import post, Body, ContentType 3 | 4 | @post('/') 5 | async def handler( 6 | user_data: StreamReader = Body(default='SomeDefault', content_type=ContentType.m_part_form_data), 7 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/03_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | @get('/') 4 | async def handler_1( 5 | user_id: Any = PathParam() 6 | ) -> ...: 7 | # "0.0.0.0:8080" 8 | 9 | @get('/') 10 | async def handler_2( 11 | path_data: Any = PathParams() 12 | ) -> ...: 13 | # {'user_id': ..., 'user_data': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/04_extract_data/03_extract_stream_reader/03_stream_reader_cant_default_text.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Handler attribute with Type `Body` cannot have a default value. 3 | 4 | Handler path: `/main.py` 5 | Handler name: `handler` 6 | Attribute name: `data` 7 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/09_ignore_injected_response.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler( 5 | response: Response, # <-- this response will be ignored 6 | ) -> Response: 7 | response.set_status(200) # <-- `200` status will be ignored 8 | 9 | return Response(status=500) # <-- new Response obj returned status `500` -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body(validate=False, content_type=ContentType.m_part_form_data), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/include.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | jsonify( 9 | Result(), 10 | include={'value'}, 11 | ) 12 | # {'someValue': 'data'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/05_http_router/example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy # <-- rapidy.Rapidy == rapidy.web.Application 2 | from rapidy.http import get, HTTPRouter 3 | 4 | @get('/get_hello') 5 | async def handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | v1_app = HTTPRouter('/v1', route_handlers=[handler]) 9 | rapidy = Rapidy(http_route_handlers=[v1_app]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/04_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body('some_data'), 10 | # or 11 | data: BodyData = Body(default_factory=lambda: 'some_data'), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/08_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body('some_data'), 10 | # or 11 | data: BodyData = Body(default_factory=lambda: 'some_data'), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | @get('/') 4 | async def handler_1( 5 | query: Any = QueryParam(), 6 | ) -> ...: 7 | # ... 8 | 9 | @get('/') 10 | async def handler_2( 11 | query_params_data: Any = QueryParams(), 12 | ) -> ...: 13 | # -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/05_response_inject_ext.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler( 5 | response: Response, # <-- current response 6 | ) -> str: 7 | some_answer: bool = ... 8 | if some_answer: 9 | response.set_status(200) 10 | return 'ok' 11 | 12 | response.set_status(500) 13 | return 'not ok' -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/04_request_validation_failure/curl__response.txt: -------------------------------------------------------------------------------- 1 | < HTTP/1.1 422 Unprocessable Entity ... 2 | { 3 | "errors": [ 4 | { 5 | "loc": ["body", "data"], 6 | "type": "string_too_short", 7 | "msg": "String should have at least 3 characters", 8 | "ctx": {"min_length": 3} 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body(validate=False, content_type=ContentType.x_www_form), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/01_extract/03_base_model.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get, Headers 3 | 4 | class HeadersData(BaseModel): 5 | host: str = Field(alias='Host') 6 | keep_alive: str = Field(alias='Keep-Alive') 7 | 8 | @get('/') 9 | async def handler( 10 | headers_data: HeadersData = Headers(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/handlers/view.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.web import View 3 | from rapidy.depends import FromDI 4 | from .providers import FooProvider 5 | 6 | class FooView(View): 7 | async def get(self, c: FromDI[int]) -> dict: 8 | return {"value": c} 9 | 10 | app = Rapidy(di_providers=[FooProvider()]) 11 | app.router.add_view('/', FooView) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/02_json_decoder/04_decoder_with_params.py: -------------------------------------------------------------------------------- 1 | import json 2 | from functools import partial 3 | from typing import Any, OrderedDict 4 | from rapidy.http import post, Body 5 | 6 | decoder = partial(json.loads, object_pairs_hook=OrderedDict) 7 | 8 | @post('/') 9 | async def handler( 10 | data: Any = Body(json_decoder=decoder), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/06_json_decoder/04_decoder_with_params.py: -------------------------------------------------------------------------------- 1 | import json 2 | from functools import partial 3 | from typing import Any, OrderedDict 4 | from rapidy.http import post, Body 5 | 6 | decoder = partial(json.loads, object_pairs_hook=OrderedDict) 7 | 8 | @post('/') 9 | async def handler( 10 | data: Any = Body(json_decoder=decoder), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/exclude.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | jsonify( 9 | Result(), 10 | exclude={'value'}, 11 | ) 12 | # {'someAnotherValue': 'another_data'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/01_extract/03_base_model.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get, Cookies 3 | 4 | class CookieData(BaseModel): 5 | user_id: str = Field(alias='UserID') 6 | user_session: str = Field(alias='User-Session') 7 | 8 | @get('/') 9 | async def handler( 10 | cookie_data: CookieData = Cookies(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_by_alias/true.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | @get( 8 | '/', 9 | response_by_alias=True, # <-- default 10 | ) 11 | async def handler() -> Result: 12 | return Result() # {"someValue": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | @get('/') 4 | async def handler_1( 5 | user_id: Any = Cookie(alias='UserID', validate=False) 6 | ) -> ...: 7 | # ... 8 | 9 | @get('/') 10 | async def handler_2( 11 | cookie_data: Any = Cookies(validate=False) 12 | ) -> ...: 13 | # # {'UserID': ..., 'User-Session': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/02_failed/01_example/response.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Validation errors: 3 | [{'loc': ('body',), 4 | 'msg': 'Input should be a valid integer, unable to parse string as an ' 5 | 'integer', 6 | 'type': 'int_parsing'}] 7 | 8 | Handler path: `main.py` 9 | Handler name: `handler` 10 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/11_validation_and_serialization/02_failed/02_example/response.txt: -------------------------------------------------------------------------------- 1 | ------------------------------ 2 | Validation errors: 3 | [{'ctx': {'max_length': 10}, 4 | 'loc': ('body', 'data'), 5 | 'msg': 'String should have at most 10 characters', 6 | 'type': 'string_too_long'}] 7 | 8 | Handler path: `main.py` 9 | Handler name: `handler` 10 | ------------------------------ -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/binary/01_extract_bytes.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body, ContentType 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: bytes = Body(), 6 | # or use any content_type 7 | user_data: bytes = Body(content_type=ContentType.stream), 8 | # also you can use pydantic validation 9 | user_data: bytes = Body(min_length=1), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/cookie/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get 2 | 3 | @get('/') 4 | async def handler() -> ...: 5 | response = Response() 6 | response.set_cookie('SomeCookie', 'SomeValue') 7 | ... 8 | 9 | @get('/') 10 | async def handler(response: Response) -> ...: 11 | response.set_cookie('SomeCookie', 'SomeValue') 12 | ... 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/aiohttp_style_example.py: -------------------------------------------------------------------------------- 1 | # aiohttp style 2 | from rapidy import web 3 | 4 | async def handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} 6 | 7 | app = web.Application() 8 | app.add_routes([ 9 | web.post( 10 | '/', 11 | handler, 12 | status_code=200, 13 | response_content_type='application/json', 14 | ), 15 | ]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_defaults/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | @get( 8 | '/', 9 | response_exclude_defaults=False, # <-- default 10 | ) 11 | async def handler() -> Result: 12 | return Result() # {"value": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_json_encoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from rapidy.http import get 3 | 4 | def custom_encoder(obj: Any) -> str: 5 | ... 6 | 7 | @get( 8 | '/', 9 | response_json_encoder=custom_encoder, 10 | ) 11 | async def handler() -> dict[str, str]: 12 | return {'hello': 'rapidy!'} # will be converted to a string by Rapidy's internal tools 13 | -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/src/providers.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from dishka import from_context, Provider, Scope 4 | 5 | from src.config import Config 6 | 7 | 8 | class ConfigProvider(Provider): 9 | scope = Scope.APP 10 | config = from_context(provides=Config) 11 | 12 | 13 | class LoggerProvider(Provider): 14 | scope = Scope.APP 15 | config = from_context(provides=logging.Logger) 16 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/index/04_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData | None = Body(), 10 | # or 11 | data: Optional[BodyData] = Body(), 12 | # or 13 | data: Union[BodyData, None] = Body(), 14 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/08_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData | None = Body(), 10 | # or 11 | data: Optional[BodyData] = Body(), 12 | # or 13 | data: Union[BodyData, None] = Body(), 14 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/04_extract_data/02_extract_bytes/01_handler_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body, ContentType 2 | 3 | @post('/') 4 | async def handler( 5 | user_data: bytes = Body(content_type=ContentType.m_part_form_data), 6 | # also you can use pydantic validation 7 | user_data: bytes = Body(content_type=ContentType.m_part_form_data, min_length=1), 8 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/di_lock_factory.py: -------------------------------------------------------------------------------- 1 | import threading 2 | 3 | container = make_container(provider, lock_factory=threading.Lock): 4 | with container(lock_factory=threading.Lock) as nested_container: 5 | ... 6 | 7 | import asyncio 8 | 9 | container = make_async_container(provider, lock_factory=asyncio.Lock) 10 | async with container(lock_factory=asyncio.Lock) as nested_container: 11 | ... 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/path/03_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, PathParam, PathParams 2 | 3 | @get('/') 4 | async def handler_1( 5 | user_id: int = PathParam(validate=False) 6 | ) -> ...: 7 | # ... 8 | 9 | @get('/') 10 | async def handler_2( 11 | path_data: int = PathParams(validate=False) 12 | ) -> ...: 13 | # {'user_id': ..., 'user_data': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/by_alias.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | jsonify( 8 | Result(), 9 | by_alias=True, # <-- default 10 | ) 11 | # {"someValue": "data"} 12 | 13 | ... 14 | 15 | jsonify( 16 | Result(), 17 | by_alias=False, 18 | ) 19 | # {"value": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_exclude_fields.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | another_value: str = Field('another_data', alias='someAnotherValue') 6 | 7 | @get( 8 | '/', 9 | response_exclude_fields={'value'}, 10 | ) 11 | async def handler() -> Result: 12 | return Result() # {"someValue": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_include_fields.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | another_value: str = Field('another_data', alias='someAnotherValue') 6 | 7 | @get( 8 | '/', 9 | response_include_fields={'value'}, 10 | ) 11 | async def handler() -> Result: 12 | return Result() # {'someValue': 'data'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/01_import/01_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import PathParam, Header, Cookie, QueryParam, Body, get 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | user_id: int = PathParam(), 6 | host: str = Header(alias='Host'), 7 | session: str = Cookie(alias='UserSession'), 8 | age_filter: str = QueryParam(alias='AgeFilter'), 9 | data: str = Body(), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/etag/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response 2 | 3 | @get('/') 4 | async def handler() -> ...: 5 | response = Response() 6 | response.etag = '33a64df551425fcc55e4d42a148795d9f25f89d4' 7 | ... 8 | 9 | @get('/') 10 | async def handler(response: Response) -> ...: 11 | response.etag = '33a64df551425fcc55e4d42a148795d9f25f89d4' 12 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/01_index/example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import post, Body, ContentType 2 | 3 | @post('/') 4 | async def handler( 5 | text_data: str = Body(content_type=ContentType.text_plain), 6 | # or 7 | text_data: str = Body(content_type=ContentType.text_html), 8 | # or any mime-type with type `text` 9 | text_data: str = Body(content_type=ContentType.text_any), 10 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Cookie, Cookies 2 | 3 | @get('/') 4 | async def handler_1( 5 | user_id: int = Cookie(alias='UserID', validate=False) 6 | ) -> ...: 7 | # ... 8 | 9 | @get('/') 10 | async def handler_2( 11 | cookie_data: int = Cookies(validate=False) 12 | ) -> ...: 13 | # # {'UserID': ..., 'User-Session': ...} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/by_alias/true.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get, Response 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | @get('/',) 8 | async def handler() -> Response: 9 | return Response( 10 | Result(), 11 | by_alias=True, # <-- default 12 | ) # {"someValue": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/01_text_response_example.txt: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Server: Nginx 3 | Content-Type: text/html; charset=utf-8 4 | Date: Wed, 10 Aug 2024 11:00:00 GMT 5 | Keep-Alive: timeout=5, max=1000 6 | Connection: Keep-Alive 7 | Age: 3464 8 | Date: Wed, 10 Aug 2024 11:10:00 GMT 9 | X-Cache-Info: caching 10 | Content-Length: 220 11 | 12 | "> 13 | (... more body data ...) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/01_import/03_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.get('/{user_id}') 6 | async def handler( 7 | user_id: int = web.PathParam(), 8 | host: str = web.Header(alias='Host'), 9 | session: str = web.Cookie(alias='UserSession'), 10 | age_filter: str = web.QueryParam(alias='AgeFilter'), 11 | data: str = web.Body(), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_defaults/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import Response, get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | 7 | @get('/') 8 | async def handler() -> Response: 9 | return Response( 10 | Result(), 11 | exclude_defaults=False, # <-- default 12 | ) # {"value": "data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/handlers/controller.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import controller, get 3 | from rapidy.depends import FromDI 4 | from .providers import FooProvider 5 | 6 | @controller('/') 7 | class MyController: 8 | @get() 9 | async def handler(self, c: FromDI[int]) -> dict: 10 | return {"value": c} 11 | 12 | app = Rapidy(http_route_handlers=[MyController], di_providers=[FooProvider()]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/middlewares.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import middleware, Request, StreamResponse, HTTPRouter 2 | from rapidy.typedefs import CallNext 3 | 4 | @middleware 5 | async def hello_middleware(request: Request, call_next: CallNext) -> StreamResponse: 6 | print('hello') 7 | return await call_next(request) 8 | 9 | router = HTTPRouter( 10 | path='/api', 11 | middlewares=[hello_middleware], 12 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/query/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, QueryParam, QueryParams 2 | 3 | @get('/') 4 | async def handler_1( 5 | query: int = QueryParam(validate=False) 6 | ) -> ...: 7 | # ... 8 | 9 | @get('/') 10 | async def handler_2( 11 | query_params_data: int = QueryParams(validate=False) 12 | ) -> ...: 13 | # -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/cookie/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import Cookie, Cookies 2 | 3 | 4 | def handler( 5 | _1: int = Cookie('1'), 6 | _2: int = Cookie(default_factory=lambda: '1'), 7 | _3: int = Cookie('1', default_factory=lambda: '1'), 8 | _4: int = Cookies('1'), 9 | _5: int = Cookies(default_factory=lambda: '1'), 10 | _6: int = Cookies('1', default_factory=lambda: '1'), 11 | ) -> None: 12 | pass 13 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/header/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import Header, Headers 2 | 3 | 4 | def handler( 5 | _1: int = Header('1'), 6 | _2: int = Header(default_factory=lambda: '1'), 7 | _3: int = Header('1', default_factory=lambda: '1'), 8 | _4: int = Headers('1'), 9 | _5: int = Headers(default_factory=lambda: '1'), 10 | _6: int = Headers('1', default_factory=lambda: '1'), 11 | ) -> None: 12 | pass 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/04_lifespan/01_example.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | from rapidy import Rapidy 4 | 5 | @asynccontextmanager 6 | async def bg_task() -> AsyncGenerator[None, None]: 7 | try: 8 | print('starting background task') 9 | yield 10 | finally: 11 | print('finishing background task') 12 | 13 | rapidy = Rapidy( 14 | lifespan=[bg_task()], 15 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/02_ignore_validation/03_no_type.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | @get('/') 4 | async def handler_1( 5 | header_host=Header(alias='Host') 6 | ) -> ...: 7 | # "0.0.0.0:8080" 8 | 9 | @get('/') 10 | async def handler_2( 11 | headers_data=Headers() 12 | ) -> ...: 13 | # -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/04_lifespan/03_add_example.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | 4 | from rapidy import Rapidy 5 | 6 | @asynccontextmanager 7 | async def bg_task() -> AsyncGenerator[None, None]: 8 | try: 9 | print('starting background task') 10 | yield 11 | finally: 12 | print('finishing background task') 13 | 14 | rapidy = Rapidy() 15 | rapidy.lifespan.append(bg_task()) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_json_encoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | def custom_encoder(obj: Any) -> str: 4 | ... 5 | 6 | @get( 7 | '/', 8 | response_json_encoder=custom_encoder, # Converts the obtained string above into a JSON object using the `custom_encoder` function 9 | ) 10 | async def handler() -> dict[str, str]: 11 | return {'hello': 'rapidy!'} # will be converted to a string by Rapidy's internal tools 12 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/01_import/02_example.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get 2 | from rapidy.parameters.http import PathParam, Header, Cookie, QueryParam, Body 3 | 4 | @get('/{user_id}') 5 | async def handler( 6 | user_id: int = PathParam(), 7 | host: str = Header(alias='Host'), 8 | session: str = Cookie(alias='UserSession'), 9 | age_filter: str = QueryParam(alias='AgeFilter'), 10 | data: str = Body(), 11 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_none/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | none_value: None = None 7 | 8 | @get( 9 | '/', 10 | response_exclude_none=False, # <-- default 11 | ) 12 | async def handler() -> Result: 13 | return Result() # {"someValue": "data", "none_value": null} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/03_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class DataEnum(Enum): 5 | test = 'test' 6 | 7 | @post('/') 8 | async def handler( 9 | data: DataEnum = Body('some_data', content_type=ContentType.text_plain), 10 | # or 11 | data: DataEnum = Body(default_factory=lambda: 'some_data', content_type=ContentType.text_plain), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/charset/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get, Charset 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | charset=Charset.utf32, 7 | # or 8 | charset='utf32', 9 | ) 10 | 11 | @get('/') 12 | async def handler(response: Response) -> ...: 13 | response.charset = Charset.utf32 14 | # or 15 | response.charset = 'utf32' 16 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/path/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import PathParam, PathParams 2 | 3 | 4 | def handler( 5 | _1: int = PathParam('1'), 6 | _2: int = PathParam(default_factory=lambda: '1'), 7 | _3: int = PathParam('1', default_factory=lambda: '1'), 8 | _4: int = PathParams('1'), 9 | _5: int = PathParams(default_factory=lambda: '1'), 10 | _6: int = PathParams('1', default_factory=lambda: '1'), 11 | ) -> None: 12 | pass 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/02_ignore_validation/02_any_type.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | @get('/') 4 | async def handler_1( 5 | header_host: Any = Header(alias='Host') 6 | ) -> ...: 7 | # "0.0.0.0:8080" 8 | 9 | @get('/') 10 | async def handler_2( 11 | headers_data: Any = Headers() 12 | ) -> ...: 13 | # -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_include_fields.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get( 9 | '/', 10 | response_include_fields={'value'}, 11 | ) 12 | async def handler() -> Result: 13 | return Result() # {'someValue': 'data'} -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/src/api.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from dishka import FromDishka as Depends 4 | from rapidy.http import get 5 | 6 | from src.config import Config 7 | from src.di import inject 8 | 9 | 10 | @get("/") 11 | @inject 12 | async def handler( 13 | config: Depends[Config], 14 | logger: Depends[logging.Logger], 15 | ) -> dict[str, str]: 16 | logger.info("Hello rapidy") 17 | return {"hello": "rapidy", "app_name": config.app_name} 18 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/index.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import HTTPRouter, get 3 | 4 | @get('/healthcheck') # /healthcheck 5 | async def healthcheck() -> str: 6 | return 'ok' 7 | 8 | @get('/hello') # /api/hello 9 | async def hello_handler() -> dict[str, str]: 10 | return {'hello': 'rapidy'} 11 | 12 | api_router = HTTPRouter('/api', [hello_handler]) 13 | 14 | rapidy = Rapidy(http_route_handlers=[healthcheck, api_router]) -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/query/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import QueryParam, QueryParams 2 | 3 | 4 | def handler( 5 | _1: int = QueryParam('1'), 6 | _2: int = QueryParam(default_factory=lambda: '1'), 7 | _3: int = QueryParam('1', default_factory=lambda: '1'), 8 | _4: int = QueryParams('1'), 9 | _5: int = QueryParams(default_factory=lambda: '1'), 10 | _6: int = QueryParams('1', default_factory=lambda: '1'), 11 | ) -> None: 12 | pass 13 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/lifespan/04_lifespan/02_example.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | from rapidy import Rapidy 4 | 5 | @asynccontextmanager 6 | async def bg_task_with_app(rapidy: Rapidy) -> AsyncGenerator[None, None]: 7 | try: 8 | print('starting background task') 9 | yield 10 | finally: 11 | print('finishing background task') 12 | 13 | rapidy = Rapidy( 14 | lifespan=[bg_task_with_app], 15 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/01_index/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class UserData(BaseModel): 5 | username: str 6 | password: str 7 | 8 | @post('/') 9 | async def handler( 10 | user_data: UserData = Body(content_type=ContentType.x_www_form), 11 | # or 12 | user_data: UserData = Body(content_type='application/x-www-form-urlencoded'), 13 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/http_errors/04_request_validation_failure/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy import Rapidy 3 | from rapidy.http import post, Body 4 | 5 | class BodyRequestSchema(BaseModel): 6 | data: str = Field(min_length=3, max_length=20) 7 | 8 | @post('/') 9 | async def handler( 10 | body: BodyRequestSchema = Body(), 11 | ) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | rapidy = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/03_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body('some_data', content_type=ContentType.m_part_form_data), 10 | # or 11 | data: BodyData = Body(default_factory=lambda: 'some_data', content_type=ContentType.m_part_form_data), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/03_default/01_default_exists.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData = Body('some_data', content_type=ContentType.x_www_form), 10 | # or 11 | data: BodyData = Body(default_factory=lambda: 'some_data', content_type=ContentType.x_www_form), 12 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/01_extract/04_dataclass.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from rapidy.http import get, Headers 3 | 4 | @dataclass 5 | class HeadersData: 6 | host: str 7 | keep_alive: str # cannot extract if header name is 'Keep-Alive' 8 | 9 | @get('/') 10 | async def handler( 11 | headers_data: HeadersData = Headers(), 12 | ) -> ...: 13 | # {"errors": [{"type": "missing", "loc": ["header", "keep_alive" ], "msg": "Field required"}]} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_fields.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get( 9 | '/', 10 | response_exclude_fields={'value'}, 11 | ) 12 | async def handler() -> Result: 13 | return Result() # {'someAnotherValue': 'another_data'} -------------------------------------------------------------------------------- /rapidy/constants.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | import json 4 | from typing import Final, TYPE_CHECKING 5 | 6 | from rapidy.version import PYDANTIC_VERSION_TUPLE 7 | 8 | if TYPE_CHECKING: 9 | from rapidy.typedefs import JSONDecoder, JSONEncoder 10 | 11 | CLIENT_MAX_SIZE: Final[int] = 1024**2 12 | 13 | PYDANTIC_IS_V1: bool = PYDANTIC_VERSION_TUPLE[0] == '1' 14 | 15 | DEFAULT_JSON_ENCODER: JSONEncoder = json.dumps 16 | DEFAULT_JSON_DECODER: JSONDecoder = json.loads 17 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/exclude_none.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | none_value: None = None 7 | 8 | jsonify( 9 | Result(), 10 | exclude_none=True, 11 | ) 12 | # {"someValue": "data"} 13 | 14 | ... 15 | 16 | jsonify( 17 | Result(), 18 | exclude_none=False, # default 19 | ) 20 | # {"someValue": "data", "none_value": null} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/json/01_obj/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class UserData(BaseModel): 5 | username: str 6 | password: str 7 | 8 | @post('/') 9 | async def handler( 10 | user_data: UserData = Body(), 11 | # or 12 | user_data: UserData = Body(content_type=ContentType.json), 13 | # or 14 | user_data: UserData = Body(content_type='application/json'), 15 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_none/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import Response, get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | none_value: None = None 7 | 8 | @get('/') 9 | async def handler() -> Response: 10 | return Response( 11 | Result(), 12 | exclude_none=False, # <-- default 13 | ) # {"someValue": "data", "none_value": null} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/include.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import Response, get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get('/') 9 | async def handler() -> Response: 10 | return Response( 11 | Result(), 12 | include={'value'}, 13 | ) # {'someValue': 'data'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/text/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | text = 'hello rapidy', 7 | ) 8 | 9 | @get('/') 10 | async def handler() -> ...: 11 | response = Response() 12 | response.text = 'hello rapidy' 13 | ... 14 | 15 | @get('/') 16 | async def handler(response: Response) -> ...: 17 | response.text = 'hello rapidy' 18 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/simple_ex.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get 3 | from rapidy.depends import FromDI, provide, Provider, Scope 4 | 5 | class FooProvider(Provider): 6 | @provide(scope=Scope.REQUEST) 7 | async def c(self) -> int: 8 | return 1 9 | 10 | @get('/') 11 | async def handler(c: FromDI[int]) -> dict: 12 | return {"value": c} 13 | 14 | app = Rapidy( 15 | http_route_handlers=[handler], 16 | di_providers=[FooProvider()], 17 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/use_from_di.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import get 3 | from rapidy.depends import FromDI, provide, Provider, Scope 4 | 5 | class FooProvider(Provider): 6 | @provide(scope=Scope.REQUEST) 7 | async def c(self) -> int: 8 | return 1 9 | 10 | @get('/') 11 | async def handler(c: FromDI[int]) -> dict: 12 | return {"value": c} 13 | 14 | app = Rapidy( 15 | http_route_handlers=[handler], 16 | di_providers=[FooProvider()], 17 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import Response, get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get('/') 9 | async def handler() -> Response: 10 | return Response( 11 | Result(), 12 | exclude={'value'}, 13 | ) # {'someAnotherValue': 'another_data'} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_exclude_defaults.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | 6 | @get( 7 | '/', 8 | exclude_defaults=False, # <-- default 9 | ) 10 | async def handler() -> Result: 11 | return Result() # {"value": "data"} 12 | 13 | ... 14 | 15 | @get( 16 | '/', 17 | exclude_defaults=True, 18 | ) 19 | async def handler() -> Result: 20 | return Result() # {} 21 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/body/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import Response, get 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | body={'hello': 'rapidy'}, 7 | ) 8 | 9 | @get('/') 10 | async def handler() -> ...: 11 | response = Response() 12 | response.body = {'hello': 'rapidy'} 13 | ... 14 | 15 | @get('/') 16 | async def handler(response: Response) -> ...: 17 | response.body = {'hello': 'rapidy'} 18 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/04_validate.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import middleware, StreamResponse, Header, Request 2 | from rapidy.typedefs import CallNext 3 | 4 | TOKEN_REGEXP = '^[Bb]earer (?P[A-Za-z0-9-_=.]*)' 5 | 6 | @middleware 7 | async def get_bearer_middleware( 8 | request: Request, 9 | call_next: CallNext, 10 | bearer_token: str = Header(alias='Authorization', pattern=TOKEN_REGEXP), 11 | ) -> StreamResponse: 12 | # process token here ... 13 | return await call_next(request) -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/external_container.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.depends import make_async_container # or: from dishka import make_async_container 3 | from .providers import FooProvider 4 | 5 | container = make_async_container(FooProvider()) 6 | 7 | async def shutdown_di_container() -> None: 8 | await container.close() 9 | 10 | app = Rapidy( 11 | di_container=container, 12 | http_route_handlers=[...], 13 | on_shutdown=[shutdown_di_container], # manual shutdown 14 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_by_alias.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | 6 | @get( 7 | '/', 8 | response_by_alias=True, # <-- default 9 | ) 10 | async def handler() -> Result: 11 | return Result() # {"someValue": "data"} 12 | 13 | ... 14 | 15 | @get( 16 | '/', 17 | response_by_alias=False, 18 | ) 19 | async def handler() -> Result: 20 | return Result() # {"value": "data"} 21 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/json_encoder.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from rapidy.http import Response, get 3 | 4 | def custom_encoder(obj: Any) -> str: 5 | ... 6 | 7 | @get('/') 8 | async def handler() -> Response: 9 | return Response( 10 | body={'hello': 'rapidy!'}, # will be converted to a string by Rapidy's internal tools 11 | json_encoder=custom_encoder, # Converts the obtained string above into a JSON object using the `custom_encoder` function 12 | ) -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/src/__main__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from rapidy import run_app 4 | 5 | from src.application import create_rapidy 6 | from src.config import Config 7 | 8 | if __name__ == "__main__": 9 | config = Config() 10 | 11 | logger = logging.getLogger(__name__) 12 | logger.setLevel(config.logger_level) 13 | 14 | rapidy = create_rapidy(logger=logger, config=config) 15 | 16 | run_app( 17 | rapidy, 18 | host=config.host, 19 | port=config.port, 20 | ) 21 | -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/tests/test_api/test_hello.py: -------------------------------------------------------------------------------- 1 | from http import HTTPStatus 2 | 3 | from aiohttp.test_utils import TestClient 4 | 5 | from src.config import Config 6 | 7 | 8 | async def test_hello( 9 | app_config: Config, 10 | rapidy_client: TestClient, 11 | ) -> None: 12 | response = await rapidy_client.get('/') 13 | 14 | assert response.status == HTTPStatus.OK 15 | 16 | json = await response.json() 17 | 18 | assert json 19 | assert json['app_name'] == app_config.app_name 20 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/body/default_mypy_out.txt: -------------------------------------------------------------------------------- 1 | cases/default/body/module.py:5: error: Incompatible default for argument "_1" (default has type "str", argument has type "int") [assignment] 2 | cases/default/body/module.py:6: error: Incompatible default for argument "_2" (default has type "str", argument has type "int") [assignment] 3 | cases/default/body/module.py:7: error: "default" and "default_factory" cannot be specified together for a requests parameter. [rapidy-param] 4 | Found 3 errors in 1 file (checked 1 source file) 5 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/body/strict_mypy_out.txt: -------------------------------------------------------------------------------- 1 | cases/default/body/module.py:5: error: Incompatible default for argument "_1" (default has type "str", argument has type "int") [assignment] 2 | cases/default/body/module.py:6: error: Incompatible default for argument "_2" (default has type "str", argument has type "int") [assignment] 3 | cases/default/body/module.py:7: error: "default" and "default_factory" cannot be specified together for a requests parameter. [rapidy-param] 4 | Found 3 errors in 1 file (checked 1 source file) 5 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/text/03_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class DataEnum(Enum): 5 | test = 'test' 6 | 7 | @post('/') 8 | async def handler( 9 | data: DataEnum | None = Body(content_type=ContentType.text_plain), 10 | # or 11 | data: Optional[DataEnum] = Body(content_type=ContentType.text_plain), 12 | # or 13 | data: Union[DataEnum, None] = Body(content_type=ContentType.text_plain), 14 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/cookies/01_extract/04_dataclass.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from rapidy.http import get, Cookies 3 | 4 | @dataclass 5 | class CookieData: 6 | UserID: str # camelCase syntax if cookie name is 'UserID' 7 | user_session: str # cannot extract if cookie name is 'User-Session' 8 | 9 | @get('/') 10 | async def handler( 11 | cookie_data: CookieData = Cookies(), 12 | ) -> ...: 13 | # {"errors": [{"type": "missing", "loc": ["cookie", "user_session"], "msg": "Field required"}]} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/02_simple_auth_middleware.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import middleware, Request, StreamResponse, Header 2 | from rapidy.typedefs import CallNext 3 | 4 | TOKEN_REGEXP = '^[Bb]earer (?P[A-Za-z0-9-_=.]*)' 5 | 6 | @middleware 7 | async def get_bearer_middleware( 8 | request: Request, 9 | call_next: CallNext, 10 | bearer_token: str = Header(alias='Authorization', pattern=TOKEN_REGEXP), 11 | ) -> StreamResponse: 12 | # process token here... 13 | return await call_next(request) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/attrs/lifespan.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | from rapidy import Rapidy 4 | from rapidy.http import HTTPRouter 5 | 6 | @asynccontextmanager 7 | async def bg_task(rapidy: Rapidy) -> AsyncGenerator[None, None]: 8 | try: 9 | print('starting background task') 10 | yield 11 | finally: 12 | print('finishing background task') 13 | 14 | router = HTTPRouter( 15 | path='/api', 16 | lifespan=[bg_task], 17 | ) -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/06_router.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import HTTPRouter, controller, get 3 | 4 | @get('/hello') 5 | async def hello_handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | @controller('/hello_controller') 9 | class HelloController: 10 | @get() 11 | async def get_hello(self) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | api_router = HTTPRouter('/api', [hello_handler, HelloController]) 15 | 16 | rapidy = Rapidy(http_route_handlers=[api_router]) 17 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/handler_response/response_exclude_unset/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get( 9 | '/', 10 | response_exclude_unset=False, # <-- default 11 | ) 12 | async def handler() -> Result: 13 | return Result(someAnotherValue='new_data') # {"someValue": "data", "someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/01_index/raw_example.txt: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost:8080 3 | Content-Type: multipart/form-data; boundary=---WD9146A 4 | Content-Length: ... 5 | 6 | ---WD9146A 7 | Content-Disposition: form-data; name="username" 8 | 9 | User 10 | ---WD9146A 11 | Content-Disposition: form-data; name="password" 12 | 13 | myAwesomePass 14 | ---WD9146A 15 | Content-Disposition: form-data; name="image"; filename="image.png"; 16 | Content-Type: image/png 17 | 18 | <... binary data ...> 19 | ---WD9146A -------------------------------------------------------------------------------- /docs/examples/examples/http_caching/expires.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, timezone 2 | from rapidy import Rapidy 3 | from rapidy.http import Response, get, HeaderName 4 | 5 | @get('/') 6 | async def handler(response: Response) -> str: 7 | content = 'success' # <-- endpoint dynamic content 8 | 9 | expire_time = datetime(2024, 3, 1, 0, 0, 0, tzinfo=timezone.utc) 10 | response.headers[HeaderName.expires] = expire_time.strftime("%a, %d %b %Y %H:%M:%S GMT") 11 | 12 | return content 13 | 14 | rapidy = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/bg_tasks/aiohttp.py: -------------------------------------------------------------------------------- 1 | from typing import AsyncGenerator 2 | from aiohttp import web 3 | 4 | async def bg_task(app: web.Application) -> None: 5 | print('run task') 6 | 7 | async def app_ctx(app: web.Application) -> AsyncGenerator[None, None]: 8 | print('starting background task') 9 | yield 10 | print('finish') 11 | 12 | app = web.Application() 13 | 14 | app.on_startup.append(bg_task) 15 | app.on_shutdown.append(bg_task) 16 | app.on_cleanup.append(bg_task) 17 | app.cleanup_ctx.append(app_ctx) -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/partial/subapp/aiohttp.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | from pydantic import BaseModel 3 | 4 | routes = web.RouteTableDef() 5 | 6 | class UserData(BaseModel): 7 | name: str 8 | age: int 9 | 10 | @routes.post('/user') 11 | async def create_user(request: web.Request) -> web.Response: 12 | # ... some aiohttp code 13 | return web.Response(text='User') 14 | 15 | v1_app = web.Application() 16 | v1_app.add_routes(routes) 17 | 18 | app = web.Application() 19 | app.add_subapp('/v1', v1_app) 20 | 21 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/03_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | from rapidy.http import post, Body, ContentType 3 | 4 | class BodyData(BaseModel): 5 | ... 6 | 7 | @post('/') 8 | async def handler( 9 | data: BodyData | None = Body(content_type=ContentType.m_part_form_data), 10 | # or 11 | data: Optional[BodyData] = Body(content_type=ContentType.m_part_form_data), 12 | # or 13 | data: Union[BodyData, None] = Body(content_type=ContentType.m_part_form_data), 14 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/x_www_form_urlencoded/03_default/02_default_optional.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel 2 | 3 | from rapidy.http import post, Body, ContentType 4 | 5 | class BodyData(BaseModel): 6 | ... 7 | 8 | @post('/') 9 | async def handler( 10 | data: BodyData | None = Body(content_type=ContentType.x_www_form), 11 | # or 12 | data: Optional[BodyData] = Body(content_type=ContentType.x_www_form), 13 | # or 14 | data: Union[BodyData, None] = Body(content_type=ContentType.x_www_form), 15 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/class_handlers/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import controller, get, PathParam 3 | 4 | @controller('/user') 5 | class UserController: 6 | @get('/{user_id}') 7 | async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]: 8 | return {'user_id': user_id} 9 | 10 | @get() 11 | async def get_all_users(self) -> list[dict[str, str]]: 12 | return [{'user_id': '1'}, {'user_id': '2'}] 13 | 14 | rapidy = Rapidy(http_route_handlers=[UserController]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_exclude_none.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | none_value: None = None 6 | 7 | @get( 8 | '/', 9 | exclude_none=False, # <-- default 10 | ) 11 | async def handler() -> Result: 12 | return Result() # {"someValue": "data", "none_value": null} 13 | 14 | ... 15 | 16 | @get( 17 | '/', 18 | exclude_none=True, 19 | ) 20 | async def handler() -> Result: 21 | return Result() # {"someValue": "data"} 22 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/exclude_unset/false.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.http import Response, get 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | @get('/') 9 | async def handler() -> Response: 10 | return Response( 11 | Result(someAnotherValue='new_data'), 12 | exclude_unset=False, # <-- default 13 | ) # {"someValue": "data", "someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/full/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post, Body 3 | from pydantic import BaseModel 4 | 5 | class UserData(BaseModel): 6 | name: str 7 | age: int 8 | 9 | @post('/user') 10 | async def create_user(user: UserData = Body()) -> dict[str, str]: 11 | return {'message': f'User {user.name}, {user.age} years old'} 12 | 13 | async def on_startup() -> None: 14 | print("App is starting...") 15 | 16 | rapidy = Rapidy( 17 | http_route_handlers=[create_user], 18 | on_startup=[on_startup], 19 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/use_from_component.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | 3 | from rapidy import Rapidy 4 | from rapidy.http import get 5 | from rapidy.depends import FromComponent, provide, Provider, Scope 6 | 7 | class FooProvider(Provider): 8 | @provide(scope=Scope.REQUEST) 9 | async def c(self) -> int: 10 | return 1 11 | 12 | @get('/') 13 | async def handler(c: Annotated[int, FromComponent()]) -> dict: 14 | return {"value": c} 15 | 16 | app = Rapidy( 17 | http_route_handlers=[handler], 18 | di_providers=[FooProvider()], 19 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/body/multipart/01_index/example.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, ConfigDict 2 | from rapidy.http import post, Body, ContentType, FileField 3 | 4 | class UserData(BaseModel): 5 | model_config = ConfigDict(arbitrary_types_allowed=True) 6 | 7 | username: str 8 | password: str 9 | image: FileField 10 | 11 | @post('/') 12 | async def handler( 13 | user_data: UserData = Body(content_type=ContentType.m_part_form_data), 14 | # or 15 | user_data: UserData = Body(content_type='multipart/form-data'), 16 | ) -> ...: -------------------------------------------------------------------------------- /docs/examples/docs/index/curl_incorrect__response.txt: -------------------------------------------------------------------------------- 1 | < HTTP/1.1 422 Unprocessable Entity ... 2 | { 3 | "errors": [ 4 | { 5 | "loc": ["body", "username"], 6 | "type": "string_too_short", 7 | "msg": "String must contain at least 3 characters, 8 | "ctx": {"min_length": 3} 9 | }, 10 | { 11 | "type": "string_too_short", 12 | "loc": ["body", "password"], 13 | "msg": "String must contain at least 8 characters", 14 | "ctx": {"min_length": 8} 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/04_controller_handler_no_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import PathParam, controller, get 3 | 4 | class UserController: 5 | @get('/{user_id}') 6 | async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]: 7 | return {'user_id': user_id} 8 | 9 | @get() 10 | async def get_all_users(self) -> list[dict[str, str]]: 11 | return [{'name': 'John'}, {'name': 'Felix'}] 12 | 13 | rapidy = Rapidy( 14 | http_route_handlers=[ 15 | controller.reg('/', UserController), 16 | ] 17 | ) 18 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/07_controller_handler_no_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import PathParam, controller, get 3 | 4 | class UserController: 5 | @get('/{user_id}') 6 | async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]: 7 | return {'user_id': user_id} 8 | 9 | @get() 10 | async def get_all_users(self) -> list[dict[str, str]]: 11 | return [{'name': 'John'}, {'name': 'Felix'}] 12 | 13 | rapidy = Rapidy( 14 | http_route_handlers=[ 15 | controller.reg('/', UserController), 16 | ] 17 | ) 18 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/headers/02_ignore_validation/01_validate_attr_false.py: -------------------------------------------------------------------------------- 1 | from multidict import CIMultiDictProxy 2 | from rapidy.http import get, Header, Headers 3 | 4 | @get('/') 5 | async def handler_1( 6 | header_host: str = Header(alias='Host', validate=False) 7 | ) -> ...: 8 | # "0.0.0.0:8080" 9 | 10 | @get('/') 11 | async def handler_2( 12 | headers_data: CIMultiDictProxy[str] = Headers(validate=False) 13 | ) -> ...: 14 | # -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/05_middleware.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import Request, StreamResponse, get, middleware 3 | from rapidy.typedefs import CallNext 4 | 5 | @middleware 6 | async def hello_middleware(request: Request, call_next: CallNext) -> StreamResponse: 7 | request['data'] = {'hello': 'rapidy'} 8 | return await call_next(request) 9 | 10 | @get('/') 11 | async def handler(request: Request) -> dict[str, str]: 12 | return request['data'] 13 | 14 | rapidy = Rapidy( 15 | http_route_handlers=[handler], 16 | middlewares=[hello_middleware], 17 | ) 18 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/07_router_no_deco.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import HTTPRouter, controller, get 3 | 4 | async def hello_handler() -> dict[str, str]: 5 | return {'hello': 'rapidy'} 6 | 7 | class HelloController: 8 | @get() 9 | async def get_hello(self) -> dict[str, str]: 10 | return {'hello': 'rapidy'} 11 | 12 | api_router = HTTPRouter( 13 | '/api', 14 | [ 15 | get.reg('/hello', hello_handler), 16 | controller.reg('/hello_controller', HelloController), 17 | ] 18 | ) 19 | 20 | rapidy = Rapidy(http_route_handlers=[api_router]) 21 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/attrs/exclude_unset.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | from rapidy.encoders import jsonify 3 | 4 | class Result(BaseModel): 5 | value: str = Field('data', alias='someValue') 6 | another_value: str = Field('another_data', alias='someAnotherValue') 7 | 8 | jsonify( 9 | Result(someAnotherValue='new_data'), 10 | exclude_unset=False, # <-- default 11 | ) 12 | # {"someValue": "data", "someAnotherValue": "new_data"} 13 | 14 | ... 15 | 16 | jsonify( 17 | Result(someAnotherValue='new_data'), 18 | exclude_unset=True, 19 | ) 20 | # {"someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/parameters/index/04_validation.py: -------------------------------------------------------------------------------- 1 | @get('/') 2 | async def handler( 3 | positive: int = QueryParam(gt=0), 4 | non_negative: int = QueryParam(ge=0), 5 | negative: int = QueryParam(lt=0), 6 | non_positive: int = QueryParam(le=0), 7 | even: int = QueryParam(multiple_of=2), 8 | love_for_pydantic: float = QueryParam(allow_inf_nan=True), 9 | short: str = QueryParam(min_length=3), 10 | long: str = QueryParam(max_length=10), 11 | regex: str = QueryParam(pattern=r'^\d*$'), 12 | precise: Decimal = QueryParam(max_digits=5, decimal_places=2), 13 | ) -> ...: 14 | ... -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/request/02_get_params_from_request_obj.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Request 2 | 3 | @get('/{user_id}') 4 | async def handler( 5 | request: Request, 6 | ) -> ...: 7 | path_params = request.match_info # dict[str, str] 8 | headers = request.headers # CIMultiDictProxy[str] 9 | cookies = request.cookies # Mapping[str, str] 10 | query_params = request.rel_url.query # MultiDictProxy[str] 11 | json_body = await request.json() # Any 12 | text_body = await request.text() # str 13 | bytes_body = await request.read() # bytes 14 | stream_body = request.content # StreamReader -------------------------------------------------------------------------------- /docs/examples/docs/index/simple_server.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import post, PathParam, Header, Body 3 | 4 | from pydantic import BaseModel, Field 5 | 6 | class BodyRequestSchema(BaseModel): 7 | username: str = Field(min_length=3, max_length=20) 8 | password: str = Field(min_length=8, max_length=40) 9 | 10 | @post('/{user_id}') 11 | async def handler( 12 | user_id: str = PathParam(), 13 | host: str = Header(alias='Host'), 14 | body: BodyRequestSchema = Body(), 15 | ) -> dict[str, str]: 16 | return {'hello': 'rapidy'} 17 | 18 | rapidy = Rapidy( 19 | http_route_handlers=[handler], 20 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/di_providers.py: -------------------------------------------------------------------------------- 1 | from typing import Annotated 2 | from aiohttp.web import run_app 3 | from rapidy import Rapidy 4 | from rapidy.http import get 5 | from rapidy.depends import provide, Provider, Scope, Resolve 6 | 7 | class FooProvider(Provider): 8 | scope = Scope.REQUEST 9 | 10 | @provide 11 | async def c(self) -> int: 12 | return 1 13 | 14 | @get('/') 15 | async def handler(c: Annotated[int, Resolve()]) -> int: 16 | return c 17 | 18 | app = Rapidy( 19 | http_route_handlers=[handler], 20 | di_providers=[FooProvider()], 21 | ) 22 | 23 | if __name__ == '__main__': 24 | run_app(app) 25 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/01_simple_middleware.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import middleware, get, Request, StreamResponse 3 | from rapidy.typedefs import CallNext 4 | 5 | @middleware 6 | async def hello_rapidy_middleware(request: Request, call_next: CallNext) -> StreamResponse: 7 | print('before') 8 | handler_response = await call_next(request) 9 | print('after') 10 | return handler_response 11 | 12 | @get('/') 13 | async def handler() -> dict[str, str]: 14 | return {'hello': 'rapidy'} 15 | 16 | rapidy = Rapidy( 17 | http_route_handlers=[handler], 18 | middlewares=[hello_rapidy_middleware], 19 | ) -------------------------------------------------------------------------------- /docs/examples/examples/projects/base/src/config.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import Final 3 | 4 | from pydantic_settings import BaseSettings, SettingsConfigDict 5 | 6 | BASE_PATH: Final[Path] = Path(__file__).resolve().parent.parent 7 | 8 | 9 | class Config(BaseSettings): 10 | app_name: str = "src" 11 | 12 | host: str = "0.0.0.0" # noqa: S104 13 | port: int = 7000 14 | 15 | logger_level: str = "INFO" 16 | # projects env 17 | 18 | model_config = SettingsConfigDict( 19 | extra="ignore", 20 | env_file=".env", 21 | env_file_encoding="utf-8", 22 | env_nested_delimiter="__", 23 | ) 24 | -------------------------------------------------------------------------------- /tests/test_mypy/strict_pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.mypy] 2 | plugins = [ 3 | "pydantic.mypy", 4 | "rapidy.mypy" 5 | ] 6 | strict = true 7 | pretty = false 8 | strict_equality = true 9 | warn_return_any = true 10 | warn_unreachable = true 11 | warn_unused_configs = true 12 | follow_imports = "normal" 13 | strict_optional = true 14 | warn_redundant_casts = true 15 | warn_unused_ignores = true 16 | check_untyped_defs = true 17 | disallow_untyped_calls = true 18 | disallow_untyped_defs = true 19 | disallow_untyped_decorators = false 20 | 21 | 22 | [tool.pydantic-mypy] 23 | init_forbid_extra = true 24 | init_typed = true 25 | warn_required_dynamic_aliases = true 26 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/http_router/sub_routes.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import HTTPRouter, get 3 | 4 | @get('/hello') # /api/v1/hello 5 | async def hello_handler_v1() -> dict[str, str | int]: 6 | return {'hello': 'rapidy', 'version': 1} 7 | 8 | @get('/hello') # /api/v2/hello 9 | async def hello_handler_v2() -> dict[str, str | int]: 10 | return {'hello': 'rapidy', 'version': 2} 11 | 12 | v1_router = HTTPRouter('/v1', [hello_handler_v1]) 13 | v2_router = HTTPRouter('/v2', [hello_handler_v2]) 14 | 15 | api_router = HTTPRouter('/api', [v1_router, v2_router]) 16 | 17 | rapidy = Rapidy(http_route_handlers=[api_router]) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/08_view_router.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.web import View 3 | 4 | class Handler(View): 5 | async def get(self) -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | async def post(self) -> dict[str, str]: 9 | return {'hello': 'rapidy'} 10 | 11 | async def put(self) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | async def patch(self) -> dict[str, str]: 15 | return {'hello': 'rapidy'} 16 | 17 | async def delete(self) -> dict[str, str]: 18 | return {'hello': 'rapidy'} 19 | 20 | rapidy = Rapidy() 21 | rapidy.router.add_view('/', Handler) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/etag/advanced_example.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | from rapidy.http import Header, HTTPNotModified, Response, get 3 | 4 | @get('/') 5 | async def handler( 6 | response: Response, 7 | if_none_match: str | None = Header(None, alias='If-None-Match'), 8 | ) -> str: 9 | content = 'success' 10 | 11 | # Generate ETag based on content 12 | etag_value = hashlib.md5(content.encode()).hexdigest() 13 | 14 | # Check If-None-Match 15 | if if_none_match and if_none_match == etag_value: 16 | raise HTTPNotModified 17 | 18 | response.etag = etag_value 19 | 20 | return content 21 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_stream_reader.py: -------------------------------------------------------------------------------- 1 | from http import HTTPStatus 2 | 3 | from aiohttp.pytest_plugin import AiohttpClient 4 | 5 | from rapidy import StreamReader, web 6 | 7 | 8 | async def test_success(aiohttp_client: AiohttpClient) -> None: 9 | async def handler(body: StreamReader = web.Body(content_type='text/*')) -> None: 10 | assert await body.read() == b'data' 11 | 12 | app = web.Application() 13 | app.add_routes([web.post('/', handler)]) 14 | 15 | client = await aiohttp_client(app) 16 | resp = await client.post('/', data='data') 17 | 18 | assert resp.status == HTTPStatus.OK, await resp.text() 19 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/attrs/response_exclude_unset.py: -------------------------------------------------------------------------------- 1 | from pydantic import BaseModel, Field 2 | 3 | class Result(BaseModel): 4 | value: str = Field('data', alias='someValue') 5 | another_value: str = Field('another_data', alias='someAnotherValue') 6 | 7 | @get( 8 | '/', 9 | exclude_unset=False, # <-- default 10 | ) 11 | async def handler() -> Result: 12 | Result(someAnotherValue='new_data') # {"someValue": "data", "someAnotherValue": "new_data"} 13 | 14 | ... 15 | 16 | @get( 17 | '/', 18 | exclude_unset=True, 19 | ) 20 | async def handler() -> Result: 21 | return Result(someAnotherValue='new_data') # {"someAnotherValue": "new_data"} -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/03_create_with_parameters.py: -------------------------------------------------------------------------------- 1 | @middleware( 2 | response_validate=..., 3 | response_type = ..., 4 | response_content_type = ..., 5 | response_charset = ..., 6 | response_zlib_executor = ..., 7 | response_zlib_executor_size = ..., 8 | response_include_fields = ..., 9 | response_exclude_fields = ..., 10 | response_by_alias = ..., 11 | response_exclude_unset = ..., 12 | response_exclude_defaults = ..., 13 | response_exclude_none = ..., 14 | response_custom_encoder = ..., 15 | response_json_encoder = ..., 16 | ) 17 | async def hello_middleware(request: Request, call_next: CallNext) -> StreamResponse: -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/12_view_add_routes.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | class Handler(web.View): 6 | async def get(self) -> dict[str, str]: 7 | return {'hello': 'rapidy'} 8 | 9 | async def post(self) -> dict[str, str]: 10 | return {'hello': 'rapidy'} 11 | 12 | async def put(self) -> dict[str, str]: 13 | return {'hello': 'rapidy'} 14 | 15 | async def patch(self) -> dict[str, str]: 16 | return {'hello': 'rapidy'} 17 | 18 | async def delete(self) -> dict[str, str]: 19 | return {'hello': 'rapidy'} 20 | 21 | rapidy = web.Application() 22 | rapidy.add_routes([web.view('/', Handler)]) 23 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/10_view_routetabledef.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.view('/') 6 | class Handler(web.View): 7 | async def get(self) -> dict[str, str]: 8 | return {'hello': 'rapidy'} 9 | 10 | async def post(self) -> dict[str, str]: 11 | return {'hello': 'rapidy'} 12 | 13 | async def put(self) -> dict[str, str]: 14 | return {'hello': 'rapidy'} 15 | 16 | async def patch(self) -> dict[str, str]: 17 | return {'hello': 'rapidy'} 18 | 19 | async def delete(self) -> dict[str, str]: 20 | return {'hello': 'rapidy'} 21 | 22 | rapidy = web.Application() 23 | rapidy.add_routes(routes) -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_annotations/test_field_name_already_exists.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | 3 | import pytest 4 | 5 | from rapidy import web 6 | from rapidy.endpoint_handlers.http.request.data_validators import AttributeAlreadyExistsError 7 | from rapidy.parameters.http import Header 8 | 9 | 10 | async def test_already_exist() -> None: 11 | async def handler( 12 | _: Any = Header(alias='same_name'), 13 | __: Any = Header(alias='same_name'), 14 | ) -> Any: 15 | return web.Response() 16 | 17 | app = web.Application() 18 | with pytest.raises(AttributeAlreadyExistsError): 19 | app.add_routes([web.post('/', handler)]) 20 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/last_modified/index.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | from rapidy.http import get, Response 3 | 4 | @get('/') 5 | async def handler() -> ...: 6 | response = Response() 7 | # or 8 | response.last_modified = datetime.datetime(2024, 2, 24, 12, 0, 0, tzinfo=datetime.timezone.utc) 9 | # or 10 | response.last_modified = 'Wed, 21 Oct 2024 07:28:00 GMT' 11 | ... 12 | 13 | @get('/') 14 | async def handler(response: Response) -> ...: 15 | # or 16 | response.last_modified = datetime.datetime(2024, 2, 24, 12, 0, 0, tzinfo=datetime.timezone.utc) 17 | # or 18 | response.last_modified = 'Wed, 21 Oct 2024 07:28:00 GMT' 19 | ... -------------------------------------------------------------------------------- /tests/test_application/test_server_info.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from pytest_aiohttp.plugin import AiohttpClient 3 | 4 | from rapidy import web 5 | 6 | 7 | @pytest.mark.parametrize('server_info_in_response', [True, False]) 8 | async def test_server_info(aiohttp_client: AiohttpClient, server_info_in_response: bool) -> None: 9 | app = web.Application(server_info_in_response=server_info_in_response) 10 | 11 | async def handler() -> None: 12 | pass 13 | 14 | app.add_routes([web.post('/', handler)]) 15 | client = await aiohttp_client(app) 16 | 17 | resp = await client.post('/') 18 | assert resp.status == 200 19 | assert bool(resp.headers.get('Server')) == server_info_in_response 20 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/dependency_injection/handlers/middleware.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import Request, StreamResponse, get, middleware 3 | from rapidy.typedefs import CallNext 4 | from rapidy.depends import FromDI 5 | from .providers import FooProvider 6 | 7 | @middleware 8 | async def some_middleware( 9 | request: Request, 10 | call_next: CallNext, 11 | c: FromDI[int], 12 | ) -> StreamResponse: 13 | print({"value": c}) 14 | return await call_next(request) 15 | 16 | @get('/') 17 | async def handler(c: FromDI[int]) -> dict: 18 | return {"value": c} 19 | 20 | app = Rapidy( 21 | middlewares=[some_middleware], 22 | http_route_handlers=[handler], 23 | di_providers=[FooProvider()], 24 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/07_lifespan.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | from rapidy import Rapidy 4 | 5 | async def startup() -> None: 6 | print('startup') 7 | 8 | async def shutdown() -> None: 9 | print('shutdown') 10 | 11 | async def cleanup() -> None: 12 | print('cleanup') 13 | 14 | @asynccontextmanager 15 | async def bg_task() -> AsyncGenerator[None, None]: 16 | try: 17 | print('starting background task') 18 | yield 19 | finally: 20 | print('finishing background task') 21 | 22 | rapidy = Rapidy( 23 | on_startup=[startup], 24 | on_shutdown=[shutdown], 25 | on_cleanup=[cleanup], 26 | lifespan=[bg_task()], 27 | ) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/05_response/01_response_management.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import middleware, StreamResponse, get, Request 3 | from rapidy.enums import ContentType 4 | from rapidy.typedefs import CallNext 5 | 6 | @middleware(response_content_type=ContentType.text_html) 7 | async def hello_rapidy_middleware(request: Request, call_next: CallNext) -> StreamResponse | str: 8 | try: 9 | return await call_next(request) 10 | except Exception: 11 | return 'server error' # Content-Type='text/html' 12 | 13 | @get('/') 14 | async def handler() -> dict[str, str]: 15 | raise Exception 16 | 17 | rapidy = Rapidy(middlewares=[hello_rapidy_middleware], http_route_handlers=[handler]) -------------------------------------------------------------------------------- /tests/test_jsonify/test_additional_attrs/test_dict.py: -------------------------------------------------------------------------------- 1 | from typing import Final 2 | 3 | from rapidy.encoders import jsonify 4 | 5 | DEFAULT: Final[str] = 'test' 6 | 7 | 8 | def test_dict_include() -> None: 9 | test_dict = {DEFAULT: DEFAULT, 'excluded_field_1': DEFAULT, 'excluded_field_2': DEFAULT} 10 | assert jsonify(test_dict, include={DEFAULT}) == {DEFAULT: DEFAULT} 11 | 12 | 13 | def test_dict_exclude_none() -> None: 14 | test_dict = {'test_null': None, DEFAULT: DEFAULT} 15 | assert jsonify(test_dict, exclude_none=True) == {DEFAULT: DEFAULT} 16 | 17 | 18 | def test_dict_exclude() -> None: 19 | test_dict = {'test_exclude': DEFAULT, DEFAULT: DEFAULT} 20 | assert jsonify(test_dict, exclude={'test_exclude'}) == {DEFAULT: DEFAULT} 21 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/09_view_router_different_path.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.web import View, PathParam 3 | 4 | class Handler(View): 5 | async def get(self, user_id: str = PathParam()) -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | async def post(self) -> dict[str, str]: 9 | return {'hello': 'rapidy'} 10 | 11 | async def put(self) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | async def patch(self) -> dict[str, str]: 15 | return {'hello': 'rapidy'} 16 | 17 | async def delete(self) -> dict[str, str]: 18 | return {'hello': 'rapidy'} 19 | 20 | rapidy = Rapidy() 21 | rapidy.router.add_get('/{user_id}', Handler) 22 | rapidy.router.add_view('/', Handler) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/middlewares/05_response/02_response_management.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import middleware, StreamResponse, get, Request, Response 3 | from rapidy.enums import ContentType 4 | from rapidy.typedefs import CallNext 5 | 6 | @middleware(response_content_type=ContentType.text_html) 7 | async def hello_rapidy_middleware(request: Request, call_next: CallNext) -> StreamResponse: 8 | try: 9 | return await call_next(request) 10 | except Exception: 11 | return Response(status=500) # Content-Type='application/octet-stream' 12 | 13 | @get('/') 14 | async def handler() -> dict[str, str]: 15 | raise Exception 16 | 17 | rapidy = Rapidy(middlewares=[hello_rapidy_middleware], http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/examples/http_caching/etag_and_if_none_match.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | 3 | from rapidy import Rapidy 4 | from rapidy.http import Header, HeaderName, HTTPNotModified, Response, get 5 | 6 | @get('/') 7 | async def handler( 8 | response: Response, 9 | if_none_match: str | None = Header(None, alias=HeaderName.if_none_match), 10 | ) -> str: 11 | content = 'success' # <-- endpoint dynamic content 12 | 13 | etag_value = hashlib.md5(content.encode()).hexdigest() 14 | 15 | if if_none_match.strip('"') == etag_value: 16 | raise HTTPNotModified 17 | 18 | response.etag = etag_value 19 | response.headers[HeaderName.cache_control] = 'public, max-age=3600' 20 | 21 | return content 22 | 23 | rapidy = Rapidy(http_route_handlers=[handler]) -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/01_aiohttp_problems/bg_tasks/rapidy.py: -------------------------------------------------------------------------------- 1 | from contextlib import asynccontextmanager 2 | from typing import AsyncGenerator 3 | from rapidy import Rapidy 4 | 5 | async def bg_task() -> None: 6 | print('run task') 7 | 8 | @asynccontextmanager 9 | async def app_ctx() -> AsyncGenerator[None, None]: 10 | print('starting background task') 11 | yield 12 | print('finishing background task') 13 | 14 | rapidy = Rapidy( 15 | on_startup=[bg_task], 16 | on_shutdown=[bg_task], 17 | on_cleanup=[bg_task], 18 | lifespan=[app_ctx()], 19 | ) 20 | # or 21 | rapidy.lifespan.on_startup.append(bg_task) 22 | rapidy.lifespan.on_shutdown.append(bg_task) 23 | rapidy.lifespan.on_cleanup.append(bg_task) 24 | rapidy.lifespan.append(app_ctx()) -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_annotations/test_no_param_type_any_must_not_raise_err.py: -------------------------------------------------------------------------------- 1 | from typing import Any 2 | from typing_extensions import Annotated 3 | 4 | import pytest 5 | 6 | from rapidy import web 7 | 8 | 9 | async def annotated_def_handler(attr: Annotated[Any, Any]) -> None: 10 | pass 11 | 12 | 13 | async def default_def_handler(attr: Any) -> None: 14 | pass 15 | 16 | 17 | @pytest.mark.parametrize( 18 | 'handler', 19 | [ 20 | pytest.param(annotated_def_handler, id='annotated-def'), 21 | pytest.param(default_def_handler, id='default-def'), 22 | ], 23 | ) 24 | def test_type_any_must_not_raise_err(handler: Any) -> None: 25 | app = web.Application() 26 | app.add_routes([web.post('/', handler)]) 27 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/11_view_routetabledef_different_path.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | @routes.view('/') 6 | class Handler(web.View): 7 | @routes.get('/{user_id}') 8 | async def get(self, user_id: str = web.PathParam()) -> dict[str, str]: 9 | return {'hello': 'rapidy'} 10 | 11 | async def post(self) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | async def put(self) -> dict[str, str]: 15 | return {'hello': 'rapidy'} 16 | 17 | async def patch(self) -> dict[str, str]: 18 | return {'hello': 'rapidy'} 19 | 20 | async def delete(self) -> dict[str, str]: 21 | return {'hello': 'rapidy'} 22 | 23 | rapidy = web.Application() 24 | rapidy.add_routes(routes) 25 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_num_attrs/test_ge.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases(1, 0)], 14 | ) 15 | async def test_ge_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=int, 22 | param=test_case.param(ge=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_num_attrs/test_gt.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases(2, 0)], 14 | ) 15 | async def test_gt_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=int, 22 | param=test_case.param(gt=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_num_attrs/test_le.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases(1, 2)], 14 | ) 15 | async def test_le_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=int, 22 | param=test_case.param(le=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_num_attrs/test_lt.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases(0, 1)], 14 | ) 15 | async def test_le_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=int, 22 | param=test_case.param(lt=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/13_view_add_routes_different_path.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | 3 | routes = web.RouteTableDef() 4 | 5 | class Handler(web.View): 6 | async def get(self, user_id: str = web.PathParam()) -> dict[str, str]: 7 | return {'hello': 'rapidy'} 8 | 9 | async def post(self) -> dict[str, str]: 10 | return {'hello': 'rapidy'} 11 | 12 | async def put(self) -> dict[str, str]: 13 | return {'hello': 'rapidy'} 14 | 15 | async def patch(self) -> dict[str, str]: 16 | return {'hello': 'rapidy'} 17 | 18 | async def delete(self) -> dict[str, str]: 19 | return {'hello': 'rapidy'} 20 | 21 | rapidy = web.Application() 22 | rapidy.add_routes([ 23 | web.get('/{user_id}', Handler), 24 | web.view('/', Handler), 25 | ]) 26 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_str_attrs/test_min_length.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases('s', '')], 14 | ) 15 | async def test_min_len_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=str, 22 | param=test_case.param(min_length=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /tests/test_http/test_server/test_handlers/test_request/test_param_attrs/test_str_attrs/test_max_length.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from aiohttp.pytest_plugin import AiohttpClient 3 | 4 | from tests.test_http.test_server.test_handlers.test_request.test_param_attrs.helpers import ( 5 | base_test, 6 | create_test_cases, 7 | TestCase, 8 | ) 9 | 10 | 11 | @pytest.mark.parametrize( 12 | 'test_case', 13 | [pytest.param(test_case, id=test_case.id) for test_case in create_test_cases('s', 'ss')], 14 | ) 15 | async def test_max_len_fields( 16 | aiohttp_client: AiohttpClient, 17 | test_case: TestCase, 18 | ) -> None: 19 | await base_test( 20 | aiohttp_client=aiohttp_client, 21 | annotation=str, 22 | param=test_case.param(max_length=1), 23 | test_case=test_case, 24 | ) 25 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/encoders/index.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from decimal import Decimal 3 | from pydantic import BaseModel, Field 4 | from rapidy.encoders import jsonify 5 | 6 | class InnerData(BaseModel): 7 | text: str = 'text' 8 | 9 | class ComplexData(BaseModel): 10 | decimal: Decimal = Decimal('1.22223311') 11 | date: datetime = datetime.now() 12 | inner: InnerData = Field(default_factory=InnerData) 13 | 14 | jsonify('text') # 'text' 15 | jsonify('text', dumps=True) # '"text"' 16 | 17 | jsonify(Decimal("1.22223311")) # '1.22223311' 18 | 19 | jsonify(ComplexData()) # {'decimal': '1.22223311', 'date': '2024-10-30T10:51:07.884276', 'inner': {'text': 'text'}} 20 | jsonify(ComplexData(), dumps=True) # '{"decimal": "1.22223311", "date": "2024-10-30T10:51:07.884276", "inner": {"text": "text"}}' -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/partial/subapp/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import web 2 | from rapidy.http import HTTPRouter, get 3 | from pydantic import BaseModel 4 | 5 | routes = web.RouteTableDef() 6 | 7 | class UserData(BaseModel): 8 | name: str 9 | age: int 10 | 11 | @routes.get('/user') 12 | async def get_user_aiohttp(request: web.Request) -> web.Response: 13 | # ... some aiohttp code 14 | return web.Response(text='User aiohttp') 15 | 16 | v1_app = web.Application() 17 | v1_app.add_routes(routes) 18 | 19 | # --- new functionality 20 | @get('/user') 21 | async def get_user_rapidy() -> str: 22 | return 'User rapidy' 23 | 24 | v2_router = HTTPRouter('/v2', route_handlers=[get_user_rapidy]) 25 | # --- 26 | 27 | app = web.Application(http_route_handlers=[v2_router]) 28 | app.add_subapp('/v1', v1_app) 29 | -------------------------------------------------------------------------------- /tests/test_mypy/cases/default/check_type/module.py: -------------------------------------------------------------------------------- 1 | from rapidy.parameters.http import Header, Headers 2 | from rapidy.web import View 3 | 4 | 5 | def handler( 6 | param_1: int = Header(1), 7 | param_2: int = Header('1'), 8 | param_3: int = Header(default_factory=lambda: '1'), 9 | param_4: int = Headers(1), 10 | param_5: int = Headers('1'), 11 | param_6: int = Headers(default_factory=lambda: '1'), 12 | ) -> None: 13 | pass 14 | 15 | 16 | class Handler(View): 17 | def post( 18 | self, 19 | param_1: int = Header(1), 20 | param_2: int = Header('1'), 21 | param_3: int = Header(default_factory=lambda: '1'), 22 | param_4: int = Headers(1), 23 | param_5: int = Headers('1'), 24 | param_6: int = Headers(default_factory=lambda: '1'), 25 | ) -> None: 26 | pass 27 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/full/aiohttp.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | from pydantic import BaseModel, ValidationError 3 | 4 | routes = web.RouteTableDef() 5 | 6 | class UserData(BaseModel): 7 | name: str 8 | age: int 9 | 10 | @routes.post('/user') 11 | async def create_user(request: web.Request) -> web.Response: 12 | data = await request.json() 13 | try: 14 | user = UserData(**data) 15 | except ValidationError as validation_err: 16 | return web.json_response({'error': validation_err.errors()}, status=400) 17 | return web.json_response({'message': f'User {user.name}, {user.age} years old'}) 18 | 19 | async def on_startup(app: web.Application) -> None: 20 | print("App is starting...") 21 | 22 | app = web.Application() 23 | app.on_startup.append(on_startup) 24 | app.add_routes(routes) 25 | 26 | web.run_app(app) -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/response/response_object/03_response_attrs/content_type/index.py: -------------------------------------------------------------------------------- 1 | from rapidy.http import get, Response, ContentType 2 | 3 | @get('/') 4 | async def handler() -> Response: 5 | return Response( 6 | body={'hello': 'rapidy!'}, 7 | content_type=ContentType.json, 8 | # or 9 | content_type='application/json', 10 | ) 11 | 12 | @get('/') 13 | async def handler() -> dict[str, str]: 14 | response = Response() 15 | 16 | response.content_type = ContentType.json 17 | # or 18 | response.content_type = 'application/json' 19 | 20 | return {'hello': 'rapidy!'} 21 | 22 | @get('/') 23 | async def handler(response: Response) -> dict[str, str]: 24 | response.content_type = ContentType.json 25 | # or 26 | response.content_type = 'application/json' 27 | 28 | return {'hello': 'rapidy!'} 29 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/partial/minor/aiohttp.py: -------------------------------------------------------------------------------- 1 | from aiohttp import web 2 | from pydantic import BaseModel, ValidationError 3 | 4 | routes = web.RouteTableDef() 5 | 6 | class UserData(BaseModel): 7 | name: str 8 | age: int 9 | 10 | @routes.post('/user') 11 | async def create_user( 12 | request: web.Request, 13 | ) -> web.Response: 14 | data = await request.json() 15 | try: 16 | user = UserData(**data) 17 | except ValidationError as validation_err: 18 | return web.json_response({'error': validation_err.errors()}, status=400) 19 | return web.json_response({'message': f'User {user.name}, {user.age} years old'}) 20 | 21 | async def on_startup(app: web.Application) -> None: 22 | print("App is starting...") 23 | 24 | app = web.Application() 25 | app.on_startup.append(on_startup) 26 | app.add_routes(routes) 27 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/application/di_skip_validation.py: -------------------------------------------------------------------------------- 1 | from rapidy.depends import make_container, Provider, provide, Scope 2 | 3 | class MainProvider(Provider): 4 | # default component is used here 5 | 6 | @provide(scope=Scope.APP) 7 | def foo(self, a: int) -> float: 8 | return a/10 9 | 10 | class AdditionalProvider(Provider): 11 | component = "X" 12 | 13 | @provide(scope=Scope.APP) 14 | def foo(self) -> int: 15 | return 1 16 | 17 | # we will get error immediately during container creation, skip validation for demo needs 18 | container = make_container(MainProvider(), AdditionalProvider(), skip_validation=True) 19 | # retrieve from component "X" 20 | container.get(int, component="X") # value 1 would be returned 21 | # retrieve from default component 22 | container.get(float) # raises NoFactoryError because int is in another component -------------------------------------------------------------------------------- /docs/docs/ru/docs/server/routing/index.md: -------------------------------------------------------------------------------- 1 | # Маршрутизация HTTP-запросов 2 | 3 | ## Описание 4 | Маршрутизация в `Rapidy` позволяет управлять обработкой HTTP-запросов, сопоставляя их с соответствующими обработчиками. 5 | 6 | ## Определение маршрутов 7 | Простейший способ определения маршрутов — использование декораторов `get`, `post`, `put`, `delete`, `head`, `options`. 8 | 9 | ```python 10 | from rapidy.http import get, post, put, delete, head, options 11 | 12 | @get('/') 13 | async def get_handler() -> ...: 14 | ... 15 | 16 | @post('/') 17 | async def post_handler() -> ...: 18 | ... 19 | 20 | @put('/') 21 | async def put_handler() -> ...: 22 | ... 23 | 24 | @delete('/') 25 | async def delete_handler() -> ...: 26 | ... 27 | 28 | @head('/') 29 | async def head_handler() -> ...: 30 | ... 31 | 32 | @options('/') 33 | async def options_handler() -> ...: 34 | ... 35 | ``` 36 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/08_router_full_example.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import controller, get, HTTPRouter 3 | 4 | @get('/hello') 5 | async def hello_handler() -> dict[str, str]: 6 | return {'hello': 'rapidy'} 7 | 8 | @controller('/hello_controller') 9 | class HelloController: 10 | @get() 11 | async def get(self) -> dict[str, str]: 12 | return {'hello': 'rapidy'} 13 | 14 | @get('/hi') 15 | async def hi_handler() -> dict[str, str]: 16 | return {'hi': 'rapidy'} 17 | 18 | @controller('/hi_controller') 19 | class HiController: 20 | @get() 21 | async def get(self) -> dict[str, str]: 22 | return {'hi': 'rapidy'} 23 | 24 | hello_api_router = HTTPRouter('/hello_api', [hello_handler, HelloController]) 25 | 26 | rapidy = Rapidy( 27 | http_route_handlers=[ 28 | hello_api_router, 29 | hi_handler, 30 | HiController, 31 | ] 32 | ) 33 | -------------------------------------------------------------------------------- /docs/examples/docs/quickstart/03_controller_handler.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import PathParam, controller, get, post, put, patch, delete 3 | 4 | @controller('/') 5 | class UserController: 6 | @get('/{user_id}') 7 | async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]: 8 | return {'user_id': user_id} 9 | 10 | @get() 11 | async def get_all_users(self) -> list[dict[str, str]]: 12 | return [{'name': 'John'}, {'name': 'Felix'}] 13 | 14 | @post() 15 | async def create_user(self) -> str: 16 | return 'ok' 17 | 18 | @put() 19 | async def update_user(self) -> str: 20 | return 'ok' 21 | 22 | @patch() 23 | async def patch_user(self) -> str: 24 | return 'ok' 25 | 26 | @delete() 27 | async def delete_user(self) -> str: 28 | return 'ok' 29 | 30 | rapidy = Rapidy(http_route_handlers=[UserController]) 31 | -------------------------------------------------------------------------------- /docs/examples/docs/aiohttp_migration/02_migration/partial/minor/rapidy.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy, web 2 | from pydantic import BaseModel, ValidationError 3 | 4 | routes = web.RouteTableDef() 5 | 6 | class UserData(BaseModel): 7 | name: str 8 | age: int 9 | 10 | @routes.post('/user') 11 | async def create_user( 12 | request: web.Request, 13 | host: str = web.Header(alias='Host'), 14 | ) -> web.Response: 15 | data = await request.json() 16 | try: 17 | user = UserData(**data) 18 | except ValidationError as validation_err: 19 | return web.Response({'error': validation_err.errors()}, status=400) 20 | return web.Response({'message': f'User {user.name}, {user.age} years old, host: {host}'}) 21 | 22 | async def on_startup(app: web.Application) -> None: 23 | print("App is starting...") 24 | 25 | app = web.Application() 26 | app.on_startup.append(on_startup) 27 | app.add_routes(routes) 28 | -------------------------------------------------------------------------------- /docs/examples/docs/docs/server/handlers/06_controller_handler.py: -------------------------------------------------------------------------------- 1 | from rapidy import Rapidy 2 | from rapidy.http import PathParam, controller, get, post, put, patch, delete 3 | 4 | @controller('/') 5 | class UserController: 6 | @get('/{user_id}') 7 | async def get_by_id(self, user_id: str = PathParam()) -> dict[str, str]: 8 | return {'user_id': user_id} 9 | 10 | @get() 11 | async def get_all_users(self) -> list[dict[str, str]]: 12 | return [{'name': 'John'}, {'name': 'Felix'}] 13 | 14 | @post() 15 | async def create_user(self) -> str: 16 | return 'ok' 17 | 18 | @put() 19 | async def update_user(self) -> str: 20 | return 'ok' 21 | 22 | @patch() 23 | async def patch_user(self) -> str: 24 | return 'ok' 25 | 26 | @delete() 27 | async def delete_user(self) -> str: 28 | return 'ok' 29 | 30 | rapidy = Rapidy(http_route_handlers=[UserController]) 31 | --------------------------------------------------------------------------------