@typespec/http-client-python 0.28.2 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +7 -6
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/constants.d.ts +6 -0
- package/dist/emitter/constants.d.ts.map +1 -0
- package/dist/emitter/constants.js +27 -0
- package/dist/emitter/constants.js.map +1 -0
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +193 -119
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/http.d.ts.map +1 -1
- package/dist/emitter/http.js +33 -1
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/lib.d.ts +37 -3
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +17 -0
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/run-python3.js +1 -1
- package/dist/emitter/run-python3.js.map +1 -1
- package/dist/emitter/system-requirements.js +6 -4
- package/dist/emitter/system-requirements.js.map +1 -1
- package/dist/emitter/types.d.ts +2 -5
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +86 -63
- package/dist/emitter/types.js.map +1 -1
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js +16 -17
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/code-model.ts +7 -13
- package/emitter/src/constants.ts +27 -0
- package/emitter/src/emitter.ts +241 -123
- package/emitter/src/http.ts +29 -1
- package/emitter/src/lib.ts +24 -0
- package/emitter/src/run-python3.ts +1 -1
- package/emitter/src/system-requirements.ts +4 -4
- package/emitter/src/types.ts +102 -62
- package/emitter/src/utils.ts +16 -18
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/emitter/test/utils.test.ts +3 -0
- package/emitter/tsconfig.build.json +2 -1
- package/emitter/tsconfig.json +2 -1
- package/eng/scripts/Build-Packages.ps1 +62 -37
- package/eng/scripts/Check-GitChanges.ps1 +30 -3
- package/eng/scripts/Functions.ps1 +54 -15
- package/eng/scripts/Generate.ps1 +42 -8
- package/eng/scripts/Generation.psm1 +44 -15
- package/eng/scripts/Initialize-Repository.ps1 +29 -11
- package/eng/scripts/Test-Packages.ps1 +47 -31
- package/eng/scripts/ci/config/eslint-ci.config.mjs +64 -0
- package/eng/scripts/ci/{mypy.ini → config/mypy.ini} +1 -1
- package/eng/scripts/ci/{pylintrc → config/pylintrc} +1 -1
- package/eng/scripts/ci/{pyrightconfig.json → config/pyrightconfig.json} +1 -1
- package/eng/scripts/ci/dev_requirements.txt +2 -1
- package/eng/scripts/ci/format.ts +232 -2
- package/eng/scripts/ci/lint.ts +223 -20
- package/eng/scripts/ci/regenerate-common.ts +411 -136
- package/eng/scripts/ci/regenerate.ts +247 -101
- package/eng/scripts/ci/run-tests.ts +507 -0
- package/eng/scripts/ci/run_apiview.py +22 -16
- package/eng/scripts/ci/run_mypy.py +34 -23
- package/eng/scripts/ci/run_pylint.py +27 -19
- package/eng/scripts/ci/run_pyright.py +9 -5
- package/eng/scripts/ci/run_sphinx_build.py +24 -9
- package/eng/scripts/ci/typecheck.ts +225 -0
- package/eng/scripts/ci/util.py +61 -25
- package/eng/scripts/ci/utils.ts +5 -5
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/eng/scripts/setup/build.ts +1 -1
- package/eng/scripts/setup/build_pygen_wheel.py +4 -3
- package/eng/scripts/setup/install.py +4 -3
- package/eng/scripts/setup/install.ts +1 -1
- package/eng/scripts/setup/prepare.py +3 -2
- package/eng/scripts/setup/prepare.ts +1 -1
- package/eng/scripts/setup/run-python3.ts +1 -1
- package/eng/scripts/setup/run_batch.py +197 -0
- package/eng/scripts/setup/run_tsp.py +3 -3
- package/eng/scripts/setup/system-requirements.ts +8 -4
- package/eng/scripts/setup/venvtools.py +1 -1
- package/generator/build/lib/pygen/__init__.py +1 -3
- package/generator/build/lib/pygen/codegen/__init__.py +0 -1
- package/generator/build/lib/pygen/codegen/models/base.py +0 -1
- package/generator/build/lib/pygen/codegen/models/client.py +2 -1
- package/generator/build/lib/pygen/codegen/models/code_model.py +1 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +0 -1
- package/generator/build/lib/pygen/codegen/models/model_type.py +1 -7
- package/generator/build/lib/pygen/codegen/models/parameter.py +16 -14
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +27 -12
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +12 -3
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +6 -2
- package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +17 -4
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +17 -11
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +176 -71
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +5 -1
- package/generator/build/lib/pygen/preprocess/__init__.py +37 -30
- package/generator/component-detection-pip-report.json +7 -7
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/__init__.py +1 -3
- package/generator/pygen/codegen/__init__.py +0 -1
- package/generator/pygen/codegen/models/base.py +0 -1
- package/generator/pygen/codegen/models/client.py +2 -1
- package/generator/pygen/codegen/models/code_model.py +1 -0
- package/generator/pygen/codegen/models/enum_type.py +0 -1
- package/generator/pygen/codegen/models/model_type.py +1 -7
- package/generator/pygen/codegen/models/parameter.py +16 -14
- package/generator/pygen/codegen/serializers/__init__.py +27 -12
- package/generator/pygen/codegen/serializers/builder_serializer.py +12 -3
- package/generator/pygen/codegen/serializers/general_serializer.py +6 -2
- package/generator/pygen/codegen/serializers/import_serializer.py +17 -4
- package/generator/pygen/codegen/serializers/parameter_serializer.py +17 -11
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +176 -71
- package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
- package/generator/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
- package/generator/pygen/codegen/templates/serialization.py.jinja2 +5 -1
- package/generator/pygen/preprocess/__init__.py +37 -30
- package/generator/pygen.egg-info/PKG-INFO +1 -2
- package/generator/pygen.egg-info/requires.txt +1 -1
- package/generator/setup.py +1 -2
- package/package.json +63 -42
- package/eng/scripts/ci/run-ci.ts +0 -89
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_commonproperties_async.py +0 -94
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_largeheader_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_nonresource_async.py +0 -36
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py +0 -205
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_resource_async.py +0 -478
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_access_async.py +0 -101
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_header_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_path_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_query_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_default_value_async.py +0 -46
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_initialization_async.py +0 -58
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_location_async.py +0 -82
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_deserialize_empty_string_as_null_async.py +0 -20
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +0 -115
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_hierrarchy_building_async.py +0 -53
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_next_link_verb_async.py +0 -28
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_override_async.py +0 -106
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_usage_async.py +0 -38
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_basic_async.py +0 -76
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_rpc_async.py +0 -22
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_standard_async.py +0 -39
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_model_async.py +0 -33
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_page_async.py +0 -80
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_scalar_async.py +0 -41
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_traits_async.py +0 -87
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_encode_duration_async.py +0 -19
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_example_basic_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py +0 -19
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_method_subscription_id_async.py +0 -248
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_async.py +0 -110
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py +0 -132
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_special_headers_client_request_id_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_versioning_previewversion_async.py +0 -53
- package/generator/test/azure/mock_api_tests/asynctests/test_client_namespace_async.py +0 -34
- package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_async.py +0 -69
- package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_enum_conflict_async.py +0 -37
- package/generator/test/azure/mock_api_tests/asynctests/test_client_overload_async.py +0 -27
- package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_async.py +0 -64
- package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_clientoperationgroup_async.py +0 -31
- package/generator/test/azure/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
- package/generator/test/azure/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
- package/generator/test/azure/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
- package/generator/test/azure/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
- package/generator/test/azure/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
- package/generator/test/azure/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -216
- package/generator/test/azure/mock_api_tests/asynctests/test_resiliency_srv_driven_async.py +0 -130
- package/generator/test/azure/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
- package/generator/test/azure/mock_api_tests/asynctests/test_service_multi_service_async.py +0 -31
- package/generator/test/azure/mock_api_tests/asynctests/test_special_words_async.py +0 -71
- package/generator/test/azure/mock_api_tests/conftest.py +0 -207
- package/generator/test/azure/mock_api_tests/data/image.jpg +0 -0
- package/generator/test/azure/mock_api_tests/data/image.png +0 -0
- package/generator/test/azure/mock_api_tests/test_azure_arm_commonproperties.py +0 -89
- package/generator/test/azure/mock_api_tests/test_azure_arm_largeheader.py +0 -27
- package/generator/test/azure/mock_api_tests/test_azure_arm_nonresource.py +0 -34
- package/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +0 -180
- package/generator/test/azure/mock_api_tests/test_azure_arm_resource.py +0 -436
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_access.py +0 -92
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_header.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_path.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_query.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_default_value.py +0 -42
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_initialization.py +0 -51
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_location.py +0 -70
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_deserialize_empty_string_as_null.py +0 -19
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +0 -104
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_hierrarchy_building.py +0 -45
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_next_link_verb.py +0 -27
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_override.py +0 -102
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_usage.py +0 -32
- package/generator/test/azure/mock_api_tests/test_azure_core_basic.py +0 -70
- package/generator/test/azure/mock_api_tests/test_azure_core_lro_rpc.py +0 -20
- package/generator/test/azure/mock_api_tests/test_azure_core_lro_standard.py +0 -32
- package/generator/test/azure/mock_api_tests/test_azure_core_model.py +0 -30
- package/generator/test/azure/mock_api_tests/test_azure_core_page.py +0 -71
- package/generator/test/azure/mock_api_tests/test_azure_core_scalar.py +0 -35
- package/generator/test/azure/mock_api_tests/test_azure_core_traits.py +0 -85
- package/generator/test/azure/mock_api_tests/test_azure_encode_duration.py +0 -18
- package/generator/test/azure/mock_api_tests/test_azure_example_basic.py +0 -29
- package/generator/test/azure/mock_api_tests/test_azure_payload_pageable.py +0 -18
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_method_subscription_id.py +0 -235
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service.py +0 -104
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py +0 -128
- package/generator/test/azure/mock_api_tests/test_azure_special_headers_client_request_id.py +0 -29
- package/generator/test/azure/mock_api_tests/test_azure_versioning_previewversion.py +0 -50
- package/generator/test/azure/mock_api_tests/test_clear_output_folder.py +0 -23
- package/generator/test/azure/mock_api_tests/test_client_namespace.py +0 -32
- package/generator/test/azure/mock_api_tests/test_client_naming.py +0 -57
- package/generator/test/azure/mock_api_tests/test_client_naming_enum_conflict.py +0 -35
- package/generator/test/azure/mock_api_tests/test_client_overload.py +0 -25
- package/generator/test/azure/mock_api_tests/test_client_structure.py +0 -60
- package/generator/test/azure/mock_api_tests/test_client_structure_clientoperationgroup.py +0 -29
- package/generator/test/azure/mock_api_tests/test_encode_duration.py +0 -60
- package/generator/test/azure/mock_api_tests/test_encode_numeric.py +0 -31
- package/generator/test/azure/mock_api_tests/test_model_base_flatten_compatibility.py +0 -251
- package/generator/test/azure/mock_api_tests/test_parameters_basic.py +0 -22
- package/generator/test/azure/mock_api_tests/test_parameters_spread.py +0 -66
- package/generator/test/azure/mock_api_tests/test_payload_content_negotiation.py +0 -33
- package/generator/test/azure/mock_api_tests/test_payload_multipart.py +0 -198
- package/generator/test/azure/mock_api_tests/test_resiliency_srv_driven.py +0 -124
- package/generator/test/azure/mock_api_tests/test_serialization_encoded_name_json.py +0 -21
- package/generator/test/azure/mock_api_tests/test_service_multi_service.py +0 -29
- package/generator/test/azure/mock_api_tests/test_special_words.py +0 -63
- package/generator/test/azure/requirements.txt +0 -125
- package/generator/test/azure/tox.ini +0 -64
- package/generator/test/data/image.jpg +0 -0
- package/generator/test/data/image.png +0 -0
- package/generator/test/dev_requirements.txt +0 -8
- package/generator/test/generic_mock_api_tests/asynctests/test_authentication_async.py +0 -140
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_array_async.py +0 -139
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +0 -132
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_datetime_async.py +0 -127
- package/generator/test/generic_mock_api_tests/asynctests/test_headasboolean_async.py +0 -35
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_body_optionality_async.py +0 -30
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_collection_format_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_path_async.py +0 -24
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_query_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_json_merge_patch_async.py +0 -98
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_media_type_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +0 -134
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py +0 -150
- package/generator/test/generic_mock_api_tests/asynctests/test_response_status_code_range_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_routes_async.py +0 -331
- package/generator/test/generic_mock_api_tests/asynctests/test_server_endpoint_not_defined_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_server_path_multiple_async.py +0 -25
- package/generator/test/generic_mock_api_tests/asynctests/test_server_path_single_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_not_versioned_async.py +0 -28
- package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_versioned_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_conditional_request_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_repeatability_async.py +0 -19
- package/generator/test/generic_mock_api_tests/asynctests/test_specs_documentation_async.py +0 -59
- package/generator/test/generic_mock_api_tests/asynctests/test_streaming_jsonl_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_array_async.py +0 -127
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_dictionary_async.py +0 -98
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_extensible_async.py +0 -25
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_fixed_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_file_async.py +0 -59
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_empty_async.py +0 -32
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_enum_discriminator_async.py +0 -70
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_nested_discriminator_async.py +0 -85
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_not_discriminated_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_recursive_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_single_discriminator_async.py +0 -67
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_usage_async.py +0 -32
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_visibility_async.py +0 -47
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_additionalproperties_async.py +0 -353
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_nullable_async.py +0 -110
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_optional_async.py +0 -197
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_valuetypes_async.py +0 -315
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_scalar_async.py +0 -60
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_union_async.py +0 -90
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_added_async.py +0 -36
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_made_optional_async.py +0 -21
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_removed_async.py +0 -39
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_renamed_from_async.py +0 -29
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_return_type_changed_from_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_type_changed_from_async.py +0 -22
- package/generator/test/generic_mock_api_tests/conftest.py +0 -75
- package/generator/test/generic_mock_api_tests/data/image.jpg +0 -0
- package/generator/test/generic_mock_api_tests/data/image.png +0 -0
- package/generator/test/generic_mock_api_tests/test_authentication.py +0 -130
- package/generator/test/generic_mock_api_tests/test_encode_array.py +0 -126
- package/generator/test/generic_mock_api_tests/test_encode_bytes.py +0 -128
- package/generator/test/generic_mock_api_tests/test_encode_datetime.py +0 -123
- package/generator/test/generic_mock_api_tests/test_headasboolean.py +0 -33
- package/generator/test/generic_mock_api_tests/test_parameters_body_optionality.py +0 -27
- package/generator/test/generic_mock_api_tests/test_parameters_collection_format.py +0 -33
- package/generator/test/generic_mock_api_tests/test_parameters_path.py +0 -22
- package/generator/test/generic_mock_api_tests/test_parameters_query.py +0 -17
- package/generator/test/generic_mock_api_tests/test_payload_json_merge_patch.py +0 -93
- package/generator/test/generic_mock_api_tests/test_payload_media_type.py +0 -25
- package/generator/test/generic_mock_api_tests/test_payload_pageable.py +0 -99
- package/generator/test/generic_mock_api_tests/test_payload_xml.py +0 -135
- package/generator/test/generic_mock_api_tests/test_response_status_code_range.py +0 -36
- package/generator/test/generic_mock_api_tests/test_routes.py +0 -285
- package/generator/test/generic_mock_api_tests/test_server_endpoint_not_defined.py +0 -17
- package/generator/test/generic_mock_api_tests/test_server_path_multiple.py +0 -21
- package/generator/test/generic_mock_api_tests/test_server_path_single.py +0 -17
- package/generator/test/generic_mock_api_tests/test_server_versions_not_versioned.py +0 -25
- package/generator/test/generic_mock_api_tests/test_server_versions_versioned.py +0 -30
- package/generator/test/generic_mock_api_tests/test_special_headers_conditional_request.py +0 -34
- package/generator/test/generic_mock_api_tests/test_special_headers_repeatability.py +0 -18
- package/generator/test/generic_mock_api_tests/test_specs_documentation.py +0 -51
- package/generator/test/generic_mock_api_tests/test_streaming_jsonl.py +0 -25
- package/generator/test/generic_mock_api_tests/test_typetest_array.py +0 -111
- package/generator/test/generic_mock_api_tests/test_typetest_dictionary.py +0 -86
- package/generator/test/generic_mock_api_tests/test_typetest_enum_extensible.py +0 -23
- package/generator/test/generic_mock_api_tests/test_typetest_enum_fixed.py +0 -25
- package/generator/test/generic_mock_api_tests/test_typetest_file.py +0 -52
- package/generator/test/generic_mock_api_tests/test_typetest_model_empty.py +0 -29
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_enum_discriminator.py +0 -58
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_nested_discriminator.py +0 -79
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_not_discriminated.py +0 -31
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_recursive.py +0 -32
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_single_discriminator.py +0 -60
- package/generator/test/generic_mock_api_tests/test_typetest_model_usage.py +0 -28
- package/generator/test/generic_mock_api_tests/test_typetest_model_visibility.py +0 -40
- package/generator/test/generic_mock_api_tests/test_typetest_property_additionalproperties.py +0 -314
- package/generator/test/generic_mock_api_tests/test_typetest_property_nullable.py +0 -102
- package/generator/test/generic_mock_api_tests/test_typetest_property_optional.py +0 -174
- package/generator/test/generic_mock_api_tests/test_typetest_property_valuetypes.py +0 -286
- package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +0 -53
- package/generator/test/generic_mock_api_tests/test_typetest_union.py +0 -80
- package/generator/test/generic_mock_api_tests/test_typetest_union_discriminated.py +0 -290
- package/generator/test/generic_mock_api_tests/test_versioning_added.py +0 -33
- package/generator/test/generic_mock_api_tests/test_versioning_made_optional.py +0 -20
- package/generator/test/generic_mock_api_tests/test_versioning_removed.py +0 -37
- package/generator/test/generic_mock_api_tests/test_versioning_renamed_from.py +0 -27
- package/generator/test/generic_mock_api_tests/test_versioning_return_type_changed_from.py +0 -17
- package/generator/test/generic_mock_api_tests/test_versioning_type_changed_from.py +0 -21
- package/generator/test/unbranded/mock_api_tests/asynctests/test_auth_flow_async.py +0 -19
- package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
- package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
- package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
- package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
- package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -218
- package/generator/test/unbranded/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/asynctests/test_special_words_async.py +0 -73
- package/generator/test/unbranded/mock_api_tests/asynctests/test_unbranded_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/conftest.py +0 -91
- package/generator/test/unbranded/mock_api_tests/data/image.jpg +0 -0
- package/generator/test/unbranded/mock_api_tests/data/image.png +0 -0
- package/generator/test/unbranded/mock_api_tests/test_auth_flow.py +0 -17
- package/generator/test/unbranded/mock_api_tests/test_encode_duration.py +0 -60
- package/generator/test/unbranded/mock_api_tests/test_encode_numeric.py +0 -32
- package/generator/test/unbranded/mock_api_tests/test_parameters_basic.py +0 -22
- package/generator/test/unbranded/mock_api_tests/test_parameters_spread.py +0 -66
- package/generator/test/unbranded/mock_api_tests/test_payload_content_negotiation.py +0 -33
- package/generator/test/unbranded/mock_api_tests/test_payload_multipart.py +0 -200
- package/generator/test/unbranded/mock_api_tests/test_serialization_encoded_name_json.py +0 -22
- package/generator/test/unbranded/mock_api_tests/test_special_words.py +0 -66
- package/generator/test/unbranded/mock_api_tests/test_unbranded.py +0 -65
- package/generator/test/unbranded/requirements.txt +0 -69
- package/generator/test/unbranded/tox.ini +0 -64
- package/generator/test/unittests/conftest.py +0 -15
- package/generator/test/unittests/requirements.txt +0 -3
- package/generator/test/unittests/test_enums.py +0 -89
- package/generator/test/unittests/test_model_base_serialization.py +0 -4906
- package/generator/test/unittests/test_model_base_xml_serialization.py +0 -1239
- package/generator/test/unittests/test_name_converter.py +0 -35
- package/generator/test/unittests/test_optional_return_type.py +0 -268
- package/generator/test/unittests/test_parameter_ordering.py +0 -104
- package/generator/test/unittests/test_sort_schema.py +0 -93
- package/generator/test/unittests/tox.ini +0 -5
- /package/eng/scripts/ci/{pyproject.toml → config/pyproject.toml} +0 -0
|
@@ -25,14 +25,7 @@ import {
|
|
|
25
25
|
emitPagingHttpMethod,
|
|
26
26
|
} from "./http.js";
|
|
27
27
|
import { PythonSdkContext } from "./lib.js";
|
|
28
|
-
import {
|
|
29
|
-
KnownTypes,
|
|
30
|
-
disableGenerationMap,
|
|
31
|
-
emitEndpointType,
|
|
32
|
-
getType,
|
|
33
|
-
simpleTypesMap,
|
|
34
|
-
typesMap,
|
|
35
|
-
} from "./types.js";
|
|
28
|
+
import { KnownTypes, emitEndpointType, getType } from "./types.js";
|
|
36
29
|
import { emitParamBase, getClientNamespace, getImplementation, getRootNamespace } from "./utils.js";
|
|
37
30
|
|
|
38
31
|
function emitBasicMethod<TServiceOperation extends SdkServiceOperation>(
|
|
@@ -263,7 +256,7 @@ function emitOperationGroups<TServiceOperation extends SdkServiceOperation>(
|
|
|
263
256
|
// operation has same clientNamespace as the operation group
|
|
264
257
|
for (const og of operationGroups) {
|
|
265
258
|
for (const op of og.operations) {
|
|
266
|
-
op.clientNamespace =
|
|
259
|
+
op.clientNamespace = og.clientNamespace;
|
|
267
260
|
}
|
|
268
261
|
}
|
|
269
262
|
|
|
@@ -366,7 +359,7 @@ export function emitCodeModel(sdkContext: PythonSdkContext) {
|
|
|
366
359
|
continue;
|
|
367
360
|
}
|
|
368
361
|
// filter out specific models not used in python, e.g., pageable models
|
|
369
|
-
if (
|
|
362
|
+
if (sdkContext.__disableGenerationMap.has(model)) {
|
|
370
363
|
continue;
|
|
371
364
|
}
|
|
372
365
|
// filter out core models
|
|
@@ -391,7 +384,7 @@ export function emitCodeModel(sdkContext: PythonSdkContext) {
|
|
|
391
384
|
}
|
|
392
385
|
|
|
393
386
|
// clear usage when a model is only used by paging
|
|
394
|
-
for (const type of
|
|
387
|
+
for (const type of sdkContext.__typesMap.values()) {
|
|
395
388
|
if (
|
|
396
389
|
type["type"] === "model" &&
|
|
397
390
|
type["referredByOperationType"] === ReferredByOperationTypes.PagingOnly &&
|
|
@@ -402,11 +395,12 @@ export function emitCodeModel(sdkContext: PythonSdkContext) {
|
|
|
402
395
|
}
|
|
403
396
|
|
|
404
397
|
codeModel["types"] = [
|
|
405
|
-
...
|
|
398
|
+
...sdkContext.__typesMap.values(),
|
|
406
399
|
...Object.values(KnownTypes),
|
|
407
|
-
...
|
|
400
|
+
...sdkContext.__simpleTypesMap.values(),
|
|
408
401
|
];
|
|
409
402
|
codeModel["crossLanguagePackageId"] = ignoreDiagnostics(getCrossLanguagePackageId(sdkContext));
|
|
403
|
+
codeModel["crossLanguageVersion"] = sdkContext.sdkPackage.crossLanguageVersion;
|
|
410
404
|
if ((sdkContext.emitContext.options as any).flavor === "azure") {
|
|
411
405
|
const metadata = { ...sdkPackage.metadata } as any;
|
|
412
406
|
if (metadata.apiVersions) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const PYODIDE_VERSION = "0.26.2";
|
|
2
|
+
export const PYGEN_WHEEL_FILENAME = "pygen-0.1.0-py3-none-any.whl";
|
|
3
|
+
export const BLOB_STORAGE_BASE_URL = "https://typespec.blob.core.windows.net/pkgs";
|
|
4
|
+
export const PACKAGE_NAME = "@typespec/http-client-python";
|
|
5
|
+
|
|
6
|
+
export const blackExcludeDirs = [
|
|
7
|
+
"__pycache__/",
|
|
8
|
+
"node_modules/",
|
|
9
|
+
"venv/",
|
|
10
|
+
"env/",
|
|
11
|
+
".direnv",
|
|
12
|
+
".eggs",
|
|
13
|
+
".git",
|
|
14
|
+
".hg",
|
|
15
|
+
".tox",
|
|
16
|
+
".venv",
|
|
17
|
+
".eggs",
|
|
18
|
+
".mypy_cache",
|
|
19
|
+
".pytest_cache",
|
|
20
|
+
".vscode",
|
|
21
|
+
".*_build/",
|
|
22
|
+
"/build/",
|
|
23
|
+
"dist",
|
|
24
|
+
".nox",
|
|
25
|
+
".svn",
|
|
26
|
+
"TempTypeSpecFiles/",
|
|
27
|
+
];
|
package/emitter/src/emitter.ts
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
import { createSdkContext } from "@azure-tools/typespec-client-generator-core";
|
|
2
|
-
import { EmitContext, NoTarget } from "@typespec/compiler";
|
|
2
|
+
import { EmitContext, emitFile, joinPaths, NoTarget } from "@typespec/compiler";
|
|
3
3
|
import { execSync } from "child_process";
|
|
4
4
|
import fs from "fs";
|
|
5
|
+
import jsyaml from "js-yaml";
|
|
5
6
|
import os from "os";
|
|
6
7
|
import path, { dirname } from "path";
|
|
7
|
-
import { loadPyodide } from "pyodide";
|
|
8
|
+
import { loadPyodide, PyodideInterface } from "pyodide";
|
|
8
9
|
import { fileURLToPath } from "url";
|
|
10
|
+
import pkgJson from "../../package.json" with { type: "json" };
|
|
9
11
|
import { emitCodeModel } from "./code-model.js";
|
|
12
|
+
import {
|
|
13
|
+
blackExcludeDirs,
|
|
14
|
+
BLOB_STORAGE_BASE_URL,
|
|
15
|
+
PACKAGE_NAME,
|
|
16
|
+
PYGEN_WHEEL_FILENAME,
|
|
17
|
+
PYODIDE_VERSION,
|
|
18
|
+
} from "./constants.js";
|
|
10
19
|
import { saveCodeModelAsYaml } from "./external-process.js";
|
|
11
20
|
import { PythonEmitterOptions, PythonSdkContext, reportDiagnostic } from "./lib.js";
|
|
12
21
|
import { runPython3 } from "./run-python3.js";
|
|
13
|
-
import { disableGenerationMap, simpleTypesMap, typesMap } from "./types.js";
|
|
14
22
|
import { getRootNamespace, md2Rst } from "./utils.js";
|
|
15
23
|
|
|
24
|
+
function getBrowserPygenWheelUrl(): string {
|
|
25
|
+
return `${BLOB_STORAGE_BASE_URL}/${PACKAGE_NAME}/${pkgJson.version}/generator/dist/${PYGEN_WHEEL_FILENAME}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
function addDefaultOptions(sdkContext: PythonSdkContext) {
|
|
17
29
|
const defaultOptions = {
|
|
18
30
|
"package-version": "1.0.0b1",
|
|
@@ -30,21 +42,24 @@ function addDefaultOptions(sdkContext: PythonSdkContext) {
|
|
|
30
42
|
const packageName = namespace.replace(/\./g, "-");
|
|
31
43
|
options["package-name"] = packageName;
|
|
32
44
|
}
|
|
33
|
-
|
|
34
|
-
// if they pass in a flavor other than azure, we want to ignore the value
|
|
35
|
-
(options as any).flavor = undefined;
|
|
36
|
-
}
|
|
45
|
+
// Set flavor based on namespace or passed option
|
|
37
46
|
if (getRootNamespace(sdkContext).toLowerCase().includes("azure")) {
|
|
38
47
|
(options as any).flavor = "azure";
|
|
48
|
+
} else if ((options as any).flavor !== "azure") {
|
|
49
|
+
// Explicitly set unbranded flavor when not azure
|
|
50
|
+
(options as any).flavor = "unbranded";
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
if (
|
|
42
54
|
options["package-pprint-name"] !== undefined &&
|
|
43
55
|
!options["package-pprint-name"].startsWith('"')
|
|
44
56
|
) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
// Only add quotes for shell compatibility when NOT using emit-yaml-only mode
|
|
58
|
+
// (emit-yaml-only passes options via JSON config files, not shell)
|
|
59
|
+
const needsShellQuoting = !options["use-pyodide"] && !options["emit-yaml-only"];
|
|
60
|
+
options["package-pprint-name"] = needsShellQuoting
|
|
61
|
+
? `"${options["package-pprint-name"]}"`
|
|
62
|
+
: `${options["package-pprint-name"]}`;
|
|
48
63
|
}
|
|
49
64
|
}
|
|
50
65
|
|
|
@@ -59,6 +74,9 @@ async function createPythonSdkContext(
|
|
|
59
74
|
return {
|
|
60
75
|
...sdkContext,
|
|
61
76
|
__endpointPathParameters: [],
|
|
77
|
+
__typesMap: new Map(),
|
|
78
|
+
__simpleTypesMap: new Map(),
|
|
79
|
+
__disableGenerationMap: new Set(),
|
|
62
80
|
};
|
|
63
81
|
}
|
|
64
82
|
|
|
@@ -100,10 +118,58 @@ function walkThroughNodes(yamlMap: Record<string, any>): Record<string, any> {
|
|
|
100
118
|
return yamlMap;
|
|
101
119
|
}
|
|
102
120
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
121
|
+
const pyodideGenerationCode = `
|
|
122
|
+
async def main():
|
|
123
|
+
import warnings
|
|
124
|
+
with warnings.catch_warnings():
|
|
125
|
+
from pygen import preprocess, codegen, black
|
|
126
|
+
preprocess.PreProcessPlugin(output_folder=outputFolder, tsp_file=yamlFile, **commandArgs).process()
|
|
127
|
+
codegen.CodeGenerator(output_folder=outputFolder, tsp_file=yamlFile, **commandArgs).process()
|
|
128
|
+
black.BlackScriptPlugin(output_folder=outputFolder, **commandArgs).process()
|
|
129
|
+
|
|
130
|
+
await main()`;
|
|
131
|
+
|
|
132
|
+
async function runPyodideGeneration(
|
|
133
|
+
pyodide: PyodideInterface,
|
|
134
|
+
outputFolder: string,
|
|
135
|
+
yamlFile: string,
|
|
136
|
+
commandArgs: Record<string, string>,
|
|
137
|
+
) {
|
|
138
|
+
const globals = pyodide.toPy({
|
|
139
|
+
outputFolder,
|
|
140
|
+
yamlFile,
|
|
141
|
+
commandArgs,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
await pyodide.runPythonAsync(pyodideGenerationCode, { globals });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function copyPyodideOutputToHost(
|
|
148
|
+
context: EmitContext<PythonEmitterOptions>,
|
|
149
|
+
pyodide: PyodideInterface,
|
|
150
|
+
memfsDir: string,
|
|
151
|
+
relativeDir: string = "",
|
|
152
|
+
) {
|
|
153
|
+
const entries = pyodide.FS.readdir(memfsDir).filter(
|
|
154
|
+
(entry: string) => entry !== "." && entry !== "..",
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
for (const entry of entries) {
|
|
158
|
+
const memfsPath = `${memfsDir}/${entry}`;
|
|
159
|
+
const relativePath = relativeDir ? `${relativeDir}/${entry}` : entry;
|
|
160
|
+
const stats = pyodide.FS.stat(memfsPath);
|
|
161
|
+
|
|
162
|
+
if (pyodide.FS.isDir(stats.mode)) {
|
|
163
|
+
await copyPyodideOutputToHost(context, pyodide, memfsPath, relativePath);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const content = pyodide.FS.readFile(memfsPath, { encoding: "utf8" });
|
|
168
|
+
await emitFile(context.program, {
|
|
169
|
+
path: joinPaths(context.emitterOutputDir, relativePath),
|
|
170
|
+
content,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
107
173
|
}
|
|
108
174
|
|
|
109
175
|
export async function $onEmit(context: EmitContext<PythonEmitterOptions>) {
|
|
@@ -124,18 +190,23 @@ export async function $onEmit(context: EmitContext<PythonEmitterOptions>) {
|
|
|
124
190
|
}
|
|
125
191
|
|
|
126
192
|
async function onEmitMain(context: EmitContext<PythonEmitterOptions>) {
|
|
127
|
-
// clean all cache to make sure emitter could work in watch mode
|
|
128
|
-
cleanAllCache();
|
|
129
|
-
|
|
130
193
|
const program = context.program;
|
|
131
194
|
const sdkContext = await createPythonSdkContext(context);
|
|
132
|
-
|
|
195
|
+
|
|
133
196
|
const outputDir = context.emitterOutputDir;
|
|
134
197
|
addDefaultOptions(sdkContext);
|
|
135
198
|
const yamlMap = emitCodeModel(sdkContext);
|
|
136
199
|
const parsedYamlMap = walkThroughNodes(yamlMap);
|
|
137
200
|
|
|
138
|
-
|
|
201
|
+
// Python emitter requires an SDK client in the TypeSpec
|
|
202
|
+
if (sdkContext.sdkPackage.clients.length === 0) {
|
|
203
|
+
reportDiagnostic(program, {
|
|
204
|
+
code: "no-sdk-clients",
|
|
205
|
+
target: NoTarget,
|
|
206
|
+
});
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
139
210
|
const resolvedOptions = sdkContext.emitContext.options;
|
|
140
211
|
const commandArgs: Record<string, string> = {};
|
|
141
212
|
if (resolvedOptions["packaging-files-config"]) {
|
|
@@ -162,99 +233,141 @@ async function onEmitMain(context: EmitContext<PythonEmitterOptions>) {
|
|
|
162
233
|
commandArgs["from-typespec"] = "true";
|
|
163
234
|
commandArgs["models-mode"] = (resolvedOptions as any)["models-mode"] ?? "dpg";
|
|
164
235
|
|
|
165
|
-
if (
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
236
|
+
if (typeof window !== "undefined") {
|
|
237
|
+
// Running in browser with Pyodide - fileURLToPath and other filesystem operations are browser-incompatible
|
|
238
|
+
const pyodide = await browserPyodidePromise;
|
|
239
|
+
|
|
240
|
+
if (!pyodide) {
|
|
241
|
+
reportDiagnostic(program, {
|
|
242
|
+
code: "browser-runtime-load-failed",
|
|
243
|
+
target: NoTarget,
|
|
244
|
+
format: { details: "" },
|
|
245
|
+
});
|
|
246
|
+
return;
|
|
175
247
|
}
|
|
176
248
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
249
|
+
const yamlFilePath = "/yaml/python-yaml-path.yaml";
|
|
250
|
+
pyodide.FS.mkdirTree("/yaml");
|
|
251
|
+
pyodide.FS.mkdirTree("/output");
|
|
252
|
+
clearMemfsDirectory(pyodide, "/output");
|
|
253
|
+
pyodide.FS.writeFile(yamlFilePath, jsyaml.dump(parsedYamlMap));
|
|
254
|
+
|
|
255
|
+
await runPyodideGeneration(pyodide, "/output", yamlFilePath, commandArgs);
|
|
256
|
+
await copyPyodideOutputToHost(context, pyodide, "/output");
|
|
257
|
+
} else {
|
|
258
|
+
const root = path.join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
259
|
+
const yamlPath = await saveCodeModelAsYaml("python-yaml-path", parsedYamlMap);
|
|
260
|
+
|
|
261
|
+
if (!program.compilerOptions.noEmit && !program.hasError()) {
|
|
262
|
+
// If emit-yaml-only mode, just copy YAML to output dir for batch processing
|
|
263
|
+
if (resolvedOptions["emit-yaml-only"]) {
|
|
264
|
+
if (!fs.existsSync(outputDir)) {
|
|
265
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
266
|
+
}
|
|
267
|
+
// Copy YAML to output dir with command args embedded
|
|
268
|
+
// Use unique filename to avoid conflicts when multiple specs share output dir
|
|
269
|
+
const configId = path.basename(yamlPath, ".yaml");
|
|
270
|
+
const batchConfig = { yamlPath, commandArgs, outputDir };
|
|
271
|
+
fs.writeFileSync(
|
|
272
|
+
path.join(outputDir, `.tsp-codegen-${configId}.json`),
|
|
273
|
+
JSON.stringify(batchConfig, null, 2),
|
|
274
|
+
);
|
|
275
|
+
return;
|
|
183
276
|
}
|
|
184
|
-
//
|
|
185
|
-
pyodide.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
277
|
+
// if not using pyodide and there's no venv, we try to create venv
|
|
278
|
+
if (!resolvedOptions["use-pyodide"] && !fs.existsSync(path.join(root, "venv"))) {
|
|
279
|
+
try {
|
|
280
|
+
await runPython3(path.join(root, "/eng/scripts/setup/install.py"));
|
|
281
|
+
await runPython3(path.join(root, "/eng/scripts/setup/prepare.py"));
|
|
282
|
+
} catch {
|
|
283
|
+
// if the python env is not ready, we use pyodide instead
|
|
284
|
+
resolvedOptions["use-pyodide"] = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (resolvedOptions["use-pyodide"]) {
|
|
289
|
+
// here we run with pyodide
|
|
290
|
+
const pyodide = await setupPyodideCall(root);
|
|
291
|
+
// create the output folder if not exists
|
|
292
|
+
if (!fs.existsSync(outputDir)) {
|
|
293
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
294
|
+
}
|
|
295
|
+
// mount output folder to pyodide
|
|
296
|
+
pyodide.FS.mkdirTree("/output");
|
|
297
|
+
pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: outputDir }, "/output");
|
|
298
|
+
// mount yaml file to pyodide
|
|
299
|
+
pyodide.FS.mkdirTree("/yaml");
|
|
300
|
+
pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: path.dirname(yamlPath) }, "/yaml");
|
|
301
|
+
await runPyodideGeneration(
|
|
302
|
+
pyodide,
|
|
303
|
+
"/output",
|
|
304
|
+
`/yaml/${path.basename(yamlPath)}`,
|
|
305
|
+
commandArgs,
|
|
306
|
+
);
|
|
213
307
|
} else {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
308
|
+
// here we run with native python
|
|
309
|
+
let venvPath = path.join(root, "venv");
|
|
310
|
+
if (fs.existsSync(path.join(venvPath, "bin"))) {
|
|
311
|
+
venvPath = path.join(venvPath, "bin", "python");
|
|
312
|
+
} else if (fs.existsSync(path.join(venvPath, "Scripts"))) {
|
|
313
|
+
venvPath = path.join(venvPath, "Scripts", "python.exe");
|
|
314
|
+
} else {
|
|
315
|
+
reportDiagnostic(program, {
|
|
316
|
+
code: "pyodide-flag-conflict",
|
|
317
|
+
target: NoTarget,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
commandArgs["output-folder"] = outputDir;
|
|
321
|
+
commandArgs["tsp-file"] = yamlPath;
|
|
322
|
+
const commandFlags = Object.entries(commandArgs)
|
|
323
|
+
.map(([key, value]) => `--${key}=${value}`)
|
|
324
|
+
.join(" ");
|
|
325
|
+
const command = `${venvPath} ${root}/eng/scripts/setup/run_tsp.py ${commandFlags}`;
|
|
326
|
+
execSync(command);
|
|
327
|
+
|
|
328
|
+
const excludePattern = blackExcludeDirs.join("|");
|
|
329
|
+
execSync(
|
|
330
|
+
`${venvPath} -m black --line-length=120 --quiet --fast ${outputDir} --exclude "${excludePattern}"`,
|
|
331
|
+
);
|
|
332
|
+
await checkForPylintIssues(outputDir, excludePattern);
|
|
218
333
|
}
|
|
219
|
-
commandArgs["output-folder"] = outputDir;
|
|
220
|
-
commandArgs["tsp-file"] = yamlPath;
|
|
221
|
-
const commandFlags = Object.entries(commandArgs)
|
|
222
|
-
.map(([key, value]) => `--${key}=${value}`)
|
|
223
|
-
.join(" ");
|
|
224
|
-
const command = `${venvPath} ${root}/eng/scripts/setup/run_tsp.py ${commandFlags}`;
|
|
225
|
-
execSync(command);
|
|
226
|
-
|
|
227
|
-
const blackExcludeDirs = [
|
|
228
|
-
"__pycache__/",
|
|
229
|
-
"node_modules/",
|
|
230
|
-
"venv/",
|
|
231
|
-
"env/",
|
|
232
|
-
".direnv",
|
|
233
|
-
".eggs",
|
|
234
|
-
".git",
|
|
235
|
-
".hg",
|
|
236
|
-
".tox",
|
|
237
|
-
".venv",
|
|
238
|
-
".eggs",
|
|
239
|
-
".mypy_cache",
|
|
240
|
-
".pytest_cache",
|
|
241
|
-
".vscode",
|
|
242
|
-
".*_build/",
|
|
243
|
-
"/build/",
|
|
244
|
-
"dist",
|
|
245
|
-
".nox",
|
|
246
|
-
".svn",
|
|
247
|
-
"TempTypeSpecFiles/",
|
|
248
|
-
];
|
|
249
|
-
const excludePattern = blackExcludeDirs.join("|");
|
|
250
|
-
execSync(
|
|
251
|
-
`${venvPath} -m black --line-length=120 --quiet --fast ${outputDir} --exclude "${excludePattern}"`,
|
|
252
|
-
);
|
|
253
|
-
checkForPylintIssues(outputDir, excludePattern);
|
|
254
334
|
}
|
|
255
335
|
}
|
|
256
336
|
}
|
|
257
337
|
|
|
338
|
+
const browserPyodidePromise: Promise<PyodideInterface> | null =
|
|
339
|
+
typeof window !== "undefined" ? setupPyodideCallBrowser() : null;
|
|
340
|
+
|
|
341
|
+
function clearMemfsDirectory(pyodide: PyodideInterface, dir: string): void {
|
|
342
|
+
const entries: string[] = pyodide.FS.readdir(dir).filter(
|
|
343
|
+
(entry: string) => entry !== "." && entry !== "..",
|
|
344
|
+
);
|
|
345
|
+
for (const entry of entries) {
|
|
346
|
+
const fullPath = `${dir}/${entry}`;
|
|
347
|
+
const stats = pyodide.FS.stat(fullPath);
|
|
348
|
+
if (pyodide.FS.isDir(stats.mode)) {
|
|
349
|
+
clearMemfsDirectory(pyodide, fullPath);
|
|
350
|
+
pyodide.FS.rmdir(fullPath);
|
|
351
|
+
} else {
|
|
352
|
+
pyodide.FS.unlink(fullPath);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async function setupPyodideCallBrowser() {
|
|
358
|
+
const pyodide = await loadPyodide({
|
|
359
|
+
indexURL: `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/`,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// use default MEMFS for browser, since NODEFS is not supported
|
|
363
|
+
pyodide.FS.mkdirTree("/generator");
|
|
364
|
+
await pyodide.loadPackage("micropip");
|
|
365
|
+
const micropip = pyodide.pyimport("micropip");
|
|
366
|
+
await micropip.install(getBrowserPygenWheelUrl());
|
|
367
|
+
|
|
368
|
+
return pyodide;
|
|
369
|
+
}
|
|
370
|
+
|
|
258
371
|
async function setupPyodideCall(root: string) {
|
|
259
372
|
const pyodide = await loadPyodide({
|
|
260
373
|
indexURL: path.dirname(fileURLToPath(import.meta.resolve("pyodide"))),
|
|
@@ -269,7 +382,7 @@ async function setupPyodideCall(root: string) {
|
|
|
269
382
|
if (lockAge > 300) {
|
|
270
383
|
fs.unlinkSync(micropipLockPath);
|
|
271
384
|
}
|
|
272
|
-
} catch
|
|
385
|
+
} catch {
|
|
273
386
|
// ignore
|
|
274
387
|
}
|
|
275
388
|
}
|
|
@@ -284,18 +397,18 @@ async function setupPyodideCall(root: string) {
|
|
|
284
397
|
);
|
|
285
398
|
await pyodide.loadPackage("micropip");
|
|
286
399
|
const micropip = pyodide.pyimport("micropip");
|
|
287
|
-
await micropip.install(
|
|
400
|
+
await micropip.install(`emfs:/generator/dist/${PYGEN_WHEEL_FILENAME}`);
|
|
288
401
|
fs.closeSync(fd);
|
|
289
402
|
fs.unlinkSync(micropipLockPath);
|
|
290
403
|
break;
|
|
291
|
-
} catch
|
|
404
|
+
} catch {
|
|
292
405
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
293
406
|
}
|
|
294
407
|
}
|
|
295
408
|
return pyodide;
|
|
296
409
|
}
|
|
297
410
|
|
|
298
|
-
function checkForPylintIssues(outputDir: string, excludePattern: string) {
|
|
411
|
+
async function checkForPylintIssues(outputDir: string, excludePattern: string) {
|
|
299
412
|
const excludeRegex = new RegExp(excludePattern);
|
|
300
413
|
|
|
301
414
|
const shouldExcludePath = (filePath: string): boolean => {
|
|
@@ -304,9 +417,8 @@ function checkForPylintIssues(outputDir: string, excludePattern: string) {
|
|
|
304
417
|
return excludeRegex.test(normalizedPath);
|
|
305
418
|
};
|
|
306
419
|
|
|
307
|
-
const processFile = (filePath: string) => {
|
|
308
|
-
let fileContent;
|
|
309
|
-
fileContent = fs.readFileSync(filePath, "utf-8");
|
|
420
|
+
const processFile = async (filePath: string) => {
|
|
421
|
+
let fileContent = await fs.promises.readFile(filePath, "utf-8");
|
|
310
422
|
const pylintDisables: string[] = [];
|
|
311
423
|
const lineEnding = fileContent.includes("\r\n") && os.platform() === "win32" ? "\r\n" : "\n";
|
|
312
424
|
const lines: string[] = fileContent.split(lineEnding);
|
|
@@ -321,32 +433,38 @@ function checkForPylintIssues(outputDir: string, excludePattern: string) {
|
|
|
321
433
|
fileContent = lines[0].includes("pylint: disable=")
|
|
322
434
|
? [lines[0] + "," + pylintDisables.join(",")].concat(lines.slice(1)).join(lineEnding)
|
|
323
435
|
: `# pylint: disable=${pylintDisables.join(",")}${lineEnding}` + fileContent;
|
|
436
|
+
await fs.promises.writeFile(filePath, fileContent);
|
|
324
437
|
}
|
|
325
438
|
}
|
|
326
|
-
|
|
327
|
-
fs.writeFileSync(filePath, fileContent);
|
|
328
439
|
};
|
|
329
440
|
|
|
330
|
-
const
|
|
441
|
+
const collectPythonFiles = async (dir: string): Promise<string[]> => {
|
|
331
442
|
if (shouldExcludePath(dir)) {
|
|
332
|
-
return;
|
|
443
|
+
return [];
|
|
333
444
|
}
|
|
334
445
|
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
446
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
447
|
+
|
|
448
|
+
const promises = entries.map(async (entry) => {
|
|
449
|
+
const filePath = path.join(dir, entry.name);
|
|
338
450
|
|
|
339
451
|
if (shouldExcludePath(filePath)) {
|
|
340
|
-
return;
|
|
452
|
+
return [];
|
|
341
453
|
}
|
|
342
454
|
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
} else if (
|
|
346
|
-
|
|
455
|
+
if (entry.isDirectory()) {
|
|
456
|
+
return collectPythonFiles(filePath);
|
|
457
|
+
} else if (entry.name.endsWith(".py")) {
|
|
458
|
+
return [filePath];
|
|
347
459
|
}
|
|
460
|
+
return [];
|
|
348
461
|
});
|
|
462
|
+
|
|
463
|
+
const results = await Promise.all(promises);
|
|
464
|
+
return results.flat();
|
|
349
465
|
};
|
|
350
466
|
|
|
351
|
-
|
|
467
|
+
// Collect all Python files first, then process in parallel
|
|
468
|
+
const pythonFiles = await collectPythonFiles(outputDir);
|
|
469
|
+
await Promise.all(pythonFiles.map(processFile));
|
|
352
470
|
}
|
package/emitter/src/http.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NoTarget } from "@typespec/compiler";
|
|
1
|
+
import { getNamespaceFullName, NoTarget } from "@typespec/compiler";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
getHttpOperationParameter,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
SdkQueryParameter,
|
|
20
20
|
SdkServiceMethod,
|
|
21
21
|
SdkServiceResponseHeader,
|
|
22
|
+
SdkType,
|
|
22
23
|
UsageFlags,
|
|
23
24
|
} from "@azure-tools/typespec-client-generator-core";
|
|
24
25
|
import { HttpStatusCodeRange } from "@typespec/http";
|
|
@@ -41,6 +42,32 @@ export enum ReferredByOperationTypes {
|
|
|
41
42
|
NonPagingOnly = 2,
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
function isEtagType(type: SdkType): boolean {
|
|
46
|
+
if (type.kind === "nullable") return isEtagType(type.type);
|
|
47
|
+
const raw = type.__raw;
|
|
48
|
+
if (!raw || raw.kind !== "Scalar") return false;
|
|
49
|
+
return (
|
|
50
|
+
raw.name === "eTag" &&
|
|
51
|
+
raw.namespace !== undefined &&
|
|
52
|
+
getNamespaceFullName(raw.namespace) === "Azure.Core"
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getEtagRole(parameter: SdkHeaderParameter): string | undefined {
|
|
57
|
+
const name = parameter.name.toLowerCase();
|
|
58
|
+
const wire = parameter.serializedName.toLowerCase();
|
|
59
|
+
// Standard If-Match / If-None-Match headers work with any type
|
|
60
|
+
if (wire === "if-match") return "ifMatch";
|
|
61
|
+
if (wire === "if-none-match") return "ifNoneMatch";
|
|
62
|
+
// Non-standard headers require Azure.Core.eTag type
|
|
63
|
+
if (!isEtagType(parameter.type)) return undefined;
|
|
64
|
+
if (name.includes("nonematch") || name.includes("none_match")) return "ifNoneMatch";
|
|
65
|
+
if (name.includes("match")) return "ifMatch";
|
|
66
|
+
if (wire.endsWith("-if-none-match")) return "ifNoneMatch";
|
|
67
|
+
if (wire.endsWith("-if-match")) return "ifMatch";
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
44
71
|
function isContentTypeParameter(parameter: SdkHeaderParameter) {
|
|
45
72
|
return parameter.serializedName.toLowerCase() === "content-type";
|
|
46
73
|
}
|
|
@@ -496,6 +523,7 @@ function emitHttpHeaderParameter(
|
|
|
496
523
|
delimiter,
|
|
497
524
|
explode,
|
|
498
525
|
clientDefaultValue,
|
|
526
|
+
etagRole: getEtagRole(parameter),
|
|
499
527
|
};
|
|
500
528
|
}
|
|
501
529
|
|