universal-mcp 0.1.21rc2__py3-none-any.whl → 0.1.22rc1__py3-none-any.whl

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.
@@ -87,34 +87,34 @@ def _openapi_type_to_python_type(schema: dict, required: bool = True) -> str:
87
87
  """
88
88
  openapi_type = schema.get("type")
89
89
 
90
-
91
- if "$ref" in schema and not openapi_type:
92
- py_type = "dict[str, Any]"
90
+ if "$ref" in schema and not openapi_type:
91
+ py_type = "dict[str, Any]"
93
92
  elif openapi_type == "array":
94
93
  items_schema = schema.get("items", {})
95
- item_type = _openapi_type_to_python_type(items_schema, required=True)
94
+ item_type = _openapi_type_to_python_type(items_schema, required=True)
96
95
  py_type = f"List[{item_type}]"
97
96
  elif openapi_type == "object":
98
-
99
97
  if schema.get("format") in ["binary", "byte"]:
100
- py_type = "bytes"
98
+ py_type = "bytes"
101
99
  else:
102
-
103
100
  if "additionalProperties" in schema and isinstance(schema["additionalProperties"], dict):
104
101
  additional_props_schema = schema["additionalProperties"]
105
-
102
+
106
103
  value_type = _openapi_type_to_python_type(additional_props_schema, required=True)
107
104
  py_type = f"dict[str, {value_type}]"
108
- elif not schema.get("properties") and not schema.get("allOf") and not schema.get("oneOf") and not schema.get("anyOf"):
109
-
110
- py_type = "dict[str, Any]"
105
+ elif (
106
+ not schema.get("properties")
107
+ and not schema.get("allOf")
108
+ and not schema.get("oneOf")
109
+ and not schema.get("anyOf")
110
+ ):
111
+ py_type = "dict[str, Any]"
111
112
  else:
112
-
113
113
  py_type = "dict[str, Any]"
114
114
  elif openapi_type == "integer":
115
115
  py_type = "int"
116
116
  elif openapi_type == "number":
117
- py_type = "float"
117
+ py_type = "float"
118
118
  elif openapi_type == "boolean":
119
119
  py_type = "bool"
120
120
  elif openapi_type == "string":
@@ -124,9 +124,8 @@ def _openapi_type_to_python_type(schema: dict, required: bool = True) -> str:
124
124
  py_type = "str"
125
125
  else:
126
126
  py_type = "str"
127
- else:
128
-
129
- py_type = "Any"
127
+ else:
128
+ py_type = "Any"
130
129
 
131
130
  if not required:
132
131
  if py_type.startswith("Optional[") and py_type.endswith("]"):
@@ -256,7 +255,7 @@ def _determine_function_name(operation: dict[str, Any], path: str, method: str)
256
255
  if "operationId" in operation:
257
256
  raw_name = operation["operationId"]
258
257
  cleaned_name = raw_name.replace(".", "_").replace("-", "_")
259
- cleaned_name_no_numbers = re.sub(r'\d+', '', cleaned_name)
258
+ cleaned_name_no_numbers = re.sub(r"\d+", "", cleaned_name)
260
259
  func_name = convert_to_snake_case(cleaned_name_no_numbers)
261
260
  else:
262
261
  # Generate name from path and method
@@ -291,7 +290,7 @@ def _generate_path_params(path: str) -> list[Parameters]:
291
290
  where="path",
292
291
  required=True,
293
292
  example=None,
294
- schema={"type": "string"}
293
+ schema={"type": "string"},
295
294
  )
296
295
  )
297
296
  except Exception as e:
@@ -340,7 +339,7 @@ def _generate_query_params(operation: dict[str, Any]) -> list[Parameters]:
340
339
  where=where,
341
340
  required=required,
342
341
  example=str(example_value) if example_value is not None else None,
343
- schema=param_schema if param_schema else {"type": type_value}
342
+ schema=param_schema if param_schema else {"type": type_value},
344
343
  )
345
344
  query_params.append(parameter)
346
345
  return query_params
@@ -372,12 +371,12 @@ def _generate_body_params(schema_to_process: dict[str, Any] | None, overall_body
372
371
  name=_sanitize_identifier(param_name),
373
372
  identifier=param_name,
374
373
  description=param_description,
375
- type=effective_param_type,
374
+ type=effective_param_type,
376
375
  where="body",
377
376
  required=param_required,
378
377
  example=str(param_example) if param_example is not None else None,
379
378
  is_file=current_is_file,
380
- schema=param_schema_details
379
+ schema=param_schema_details,
381
380
  )
382
381
  )
383
382
  # print(f"[DEBUG] Final body_params list generated: {body_params}") # DEBUG
@@ -403,10 +402,10 @@ def _generate_method_code(path, method, operation):
403
402
 
404
403
  # --- Determine Function Name and Basic Operation Details ---
405
404
  func_name = _determine_function_name(operation, path, method)
406
- method_lower = method.lower() # Define method_lower earlier
407
- operation.get("summary", "") # Ensure summary is accessed if needed elsewhere
408
- operation.get("tags", []) # Ensure tags are accessed if needed elsewhere
409
-
405
+ method_lower = method.lower() # Define method_lower earlier
406
+ operation.get("summary", "") # Ensure summary is accessed if needed elsewhere
407
+ operation.get("tags", []) # Ensure tags are accessed if needed elsewhere
408
+
410
409
  # --- Generate Path and Query Parameters (pre-aliasing) ---
411
410
  path_params = _generate_path_params(path)
412
411
  query_params = _generate_query_params(operation)
@@ -415,7 +414,7 @@ def _generate_method_code(path, method, operation):
415
414
  # This section selects the primary content type and its schema to be used for the request body.
416
415
  has_body = "requestBody" in operation
417
416
  body_schema_to_use = None
418
- selected_content_type = None # This will hold the chosen content type string
417
+ selected_content_type = None # This will hold the chosen content type string
419
418
 
420
419
  if has_body:
421
420
  request_body_spec = operation["requestBody"]
@@ -428,7 +427,7 @@ def _generate_method_code(path, method, operation):
428
427
  "application/octet-stream",
429
428
  "text/plain",
430
429
  ]
431
-
430
+
432
431
  found_preferred = False
433
432
  for ct in preferred_content_types:
434
433
  if ct in request_body_content_map:
@@ -436,25 +435,25 @@ def _generate_method_code(path, method, operation):
436
435
  body_schema_to_use = request_body_content_map[ct].get("schema")
437
436
  found_preferred = True
438
437
  break
439
-
440
- if not found_preferred: # Check for image/* if no direct match yet
438
+
439
+ if not found_preferred: # Check for image/* if no direct match yet
441
440
  for ct_key in request_body_content_map:
442
441
  if ct_key.startswith("image/"):
443
442
  selected_content_type = ct_key
444
443
  body_schema_to_use = request_body_content_map[ct_key].get("schema")
445
444
  found_preferred = True
446
445
  break
447
-
448
- if not found_preferred and request_body_content_map: # Fallback to first listed
446
+
447
+ if not found_preferred and request_body_content_map: # Fallback to first listed
449
448
  first_ct_key = next(iter(request_body_content_map))
450
449
  selected_content_type = first_ct_key
451
450
  body_schema_to_use = request_body_content_map[first_ct_key].get("schema")
452
451
 
453
452
  # --- Generate Body Parameters (based on selected schema, pre-aliasing) ---
454
- if body_schema_to_use: # If a schema was actually found for the selected content type
453
+ if body_schema_to_use: # If a schema was actually found for the selected content type
455
454
  body_params = _generate_body_params(
456
- body_schema_to_use, # Pass the specific schema
457
- operation.get("requestBody", {}).get("required", False) # Pass the overall body requirement
455
+ body_schema_to_use, # Pass the specific schema
456
+ operation.get("requestBody", {}).get("required", False), # Pass the overall body requirement
458
457
  )
459
458
  else:
460
459
  body_params = []
@@ -526,29 +525,36 @@ def _generate_method_code(path, method, operation):
526
525
  current_body_param_names.add(b_param.name)
527
526
  # --- End Alias duplicate parameter names ---
528
527
 
529
-
530
528
  # --- Determine Return Type and Body Characteristics ---
531
529
  return_type = _determine_return_type(operation)
532
530
 
533
- body_required = has_body and operation["requestBody"].get("required", False) # Remains useful
534
-
531
+ body_required = has_body and operation["requestBody"].get("required", False) # Remains useful
532
+
535
533
  is_array_body = False
536
- has_empty_body = False
534
+ has_empty_body = False
537
535
 
538
- if has_body and body_schema_to_use: # Use the determined body_schema_to_use
536
+ if has_body and body_schema_to_use: # Use the determined body_schema_to_use
539
537
  if body_schema_to_use.get("type") == "array":
540
538
  is_array_body = True
541
-
539
+
542
540
  # Check for cases that might lead to an "empty" body parameter (for JSON) in the signature,
543
541
  # or indicate a raw body type where _generate_body_params wouldn't create named params.
544
- if not body_params and not is_array_body and selected_content_type == "application/json" and \
545
- (body_schema_to_use == {} or \
546
- (body_schema_to_use.get("type") == "object" and \
547
- not body_schema_to_use.get("properties") and \
548
- not body_schema_to_use.get("allOf") and \
549
- not body_schema_to_use.get("oneOf") and \
550
- not body_schema_to_use.get("anyOf"))):
551
- has_empty_body = True # Indicates a generic 'request_body: dict = None' might be needed for empty JSON
542
+ if (
543
+ not body_params
544
+ and not is_array_body
545
+ and selected_content_type == "application/json"
546
+ and (
547
+ body_schema_to_use == {}
548
+ or (
549
+ body_schema_to_use.get("type") == "object"
550
+ and not body_schema_to_use.get("properties")
551
+ and not body_schema_to_use.get("allOf")
552
+ and not body_schema_to_use.get("oneOf")
553
+ and not body_schema_to_use.get("anyOf")
554
+ )
555
+ )
556
+ ):
557
+ has_empty_body = True # Indicates a generic 'request_body: dict = None' might be needed for empty JSON
552
558
 
553
559
  # --- Build Function Arguments for Signature ---
554
560
  # This section constructs the list of arguments (required and optional)
@@ -588,8 +594,8 @@ def _generate_method_code(path, method, operation):
588
594
  # Process Body Parameters / Request Body
589
595
  # This list tracks the *final* names of parameters in the signature that come from the request body,
590
596
  final_request_body_arg_names_for_signature = []
591
- final_empty_body_param_name = None # For the specific case of has_empty_body (empty JSON object)
592
- raw_body_param_name = None # For raw content like octet-stream, text/plain, image/*
597
+ final_empty_body_param_name = None # For the specific case of has_empty_body (empty JSON object)
598
+ raw_body_param_name = None # For raw content like octet-stream, text/plain, image/*
593
599
 
594
600
  if has_body:
595
601
  current_arg_names_set = set(required_args) | {arg.split("=")[0] for arg in optional_args}
@@ -624,11 +630,17 @@ def _generate_method_code(path, method, operation):
624
630
  final_request_body_arg_names_for_signature.append(final_array_param_name)
625
631
 
626
632
  # New: Handle raw body parameter (if body_params is empty but body is expected and not array/empty JSON)
627
- elif not body_params and not is_array_body and selected_content_type and selected_content_type not in ["application/json", "application/x-www-form-urlencoded", "multipart/form-data"]:
633
+ elif (
634
+ not body_params
635
+ and not is_array_body
636
+ and selected_content_type
637
+ and selected_content_type
638
+ not in ["application/json", "application/x-www-form-urlencoded", "multipart/form-data"]
639
+ ):
628
640
  # This branch is for raw content types like application/octet-stream, text/plain, image/*
629
641
  # where _generate_body_params returned an empty list because the schema isn't an object with properties.
630
642
  raw_body_param_name_base = "body_content"
631
-
643
+
632
644
  temp_raw_body_name = raw_body_param_name_base
633
645
  counter = 1
634
646
  is_first_suffix_attempt = True
@@ -643,15 +655,15 @@ def _generate_method_code(path, method, operation):
643
655
 
644
656
  # For signature with types
645
657
  # Determine type based on selected_content_type for raw body
646
- raw_body_schema_for_type = {"type": "string", "format": "binary"} # Default to bytes
658
+ raw_body_schema_for_type = {"type": "string", "format": "binary"} # Default to bytes
647
659
  if selected_content_type and "text" in selected_content_type:
648
660
  raw_body_schema_for_type = {"type": "string"}
649
661
  elif selected_content_type and selected_content_type.startswith("image/"):
650
- raw_body_schema_for_type = {"type": "string", "format": "binary"} # image is bytes
651
-
662
+ raw_body_schema_for_type = {"type": "string", "format": "binary"} # image is bytes
663
+
652
664
  raw_body_py_type = _openapi_type_to_python_type(raw_body_schema_for_type, required=body_required)
653
665
 
654
- if body_required: # If the raw body itself is required
666
+ if body_required: # If the raw body itself is required
655
667
  required_args.append(raw_body_param_name)
656
668
  signature_required_args_typed.append(f"{raw_body_param_name}: {raw_body_py_type}")
657
669
  else:
@@ -659,13 +671,13 @@ def _generate_method_code(path, method, operation):
659
671
  signature_optional_args_typed.append(f"{raw_body_param_name}: {raw_body_py_type} = None")
660
672
  final_request_body_arg_names_for_signature.append(raw_body_param_name)
661
673
 
662
- elif body_params: # Object body with discernible properties
674
+ elif body_params: # Object body with discernible properties
663
675
  for param in body_params: # Iterate ALIASED body_params
664
- arg_name_for_sig = param.name #final aliased name (e.g., "id_body")
676
+ arg_name_for_sig = param.name # final aliased name (e.g., "id_body")
665
677
 
666
- # Defensive check against already added args
678
+ # Defensive check against already added args
667
679
  current_arg_names_set_loop = set(required_args) | {arg.split("=")[0] for arg in optional_args}
668
-
680
+
669
681
  # For signature with types
670
682
  param_py_type = _openapi_type_to_python_type(param.schema, required=param.required)
671
683
 
@@ -679,11 +691,16 @@ def _generate_method_code(path, method, operation):
679
691
  signature_optional_args_typed.append(f"{arg_name_for_sig}: {param_py_type} = None")
680
692
  final_request_body_arg_names_for_signature.append(arg_name_for_sig)
681
693
 
694
+ if (
695
+ has_empty_body
696
+ and selected_content_type == "application/json"
697
+ and not body_params
698
+ and not is_array_body
699
+ and not raw_body_param_name
700
+ ):
701
+ empty_body_param_name_base = "request_body" # For empty JSON object
702
+ current_arg_names_set = set(required_args) | {arg.split("=")[0] for arg in optional_args}
682
703
 
683
- if has_empty_body and selected_content_type == "application/json" and not body_params and not is_array_body and not raw_body_param_name:
684
- empty_body_param_name_base = "request_body" # For empty JSON object
685
- current_arg_names_set = set(required_args) | {arg.split('=')[0] for arg in optional_args}
686
-
687
704
  final_empty_body_param_name = empty_body_param_name_base
688
705
  counter = 1
689
706
  is_first_suffix_attempt = True
@@ -710,19 +727,19 @@ def _generate_method_code(path, method, operation):
710
727
 
711
728
  # Combine required and optional arguments FOR DOCSTRING (as before, without types)
712
729
  args = required_args + optional_args
713
- print(f"[DEBUG] Final combined args for DOCSTRING: {args}") # DEBUG
730
+ print(f"[DEBUG] Final combined args for DOCSTRING: {args}") # DEBUG
714
731
 
715
732
  # Combine required and optional arguments FOR SIGNATURE (with types)
716
733
  signature_args_combined_typed = signature_required_args_typed + signature_optional_args_typed
717
- print(f"[DEBUG] Final combined args for SIGNATURE: {signature_args_combined_typed}") # DEBUG
734
+ print(f"[DEBUG] Final combined args for SIGNATURE: {signature_args_combined_typed}") # DEBUG
718
735
 
719
- # ----- Build Docstring -----
736
+ # ----- Build Docstring -----
720
737
  # This section constructs the entire docstring for the generated method,
721
738
  # including summary, argument descriptions, return type, and tags.
722
739
  docstring_parts = []
723
740
  # NEW: Add OpenAPI path as the first line of the docstring
724
- openapi_path_comment_for_docstring = f"# openapi_path: {path}"
725
- docstring_parts.append(openapi_path_comment_for_docstring)
741
+ # openapi_path_comment_for_docstring = f"# openapi_path: {path}"
742
+ # docstring_parts.append(openapi_path_comment_for_docstring)
726
743
 
727
744
  return_type = _determine_return_type(operation)
728
745
 
@@ -737,7 +754,7 @@ def _generate_method_code(path, method, operation):
737
754
  # Args
738
755
  args_doc_lines = []
739
756
  param_details = {}
740
-
757
+
741
758
  # Create a combined list of all parameter objects (path, query, body) to fetch details for docstring
742
759
  all_parameter_objects_for_docstring = path_params + query_params + body_params
743
760
 
@@ -748,18 +765,18 @@ def _generate_method_code(path, method, operation):
748
765
  param_details[param_obj.name] = param_obj
749
766
 
750
767
  # Fetch request body example
751
- example_data = None # Initialize example_data here for wider scope
768
+ example_data = None # Initialize example_data here for wider scope
752
769
 
753
770
  if has_body:
754
771
  try:
755
772
  json_content = operation["requestBody"]["content"]["application/json"]
756
- #From direct content definition
773
+ # From direct content definition
757
774
  if "example" in json_content:
758
775
  example_data = json_content["example"]
759
776
  elif "examples" in json_content and json_content["examples"]:
760
777
  first_example_key = list(json_content["examples"].keys())[0]
761
778
  example_data = json_content["examples"][first_example_key].get("value")
762
- #If not found directly, try from resolved body schema (for nested/referenced examples)
779
+ # If not found directly, try from resolved body schema (for nested/referenced examples)
763
780
  if example_data is None and body_schema_to_use and "example" in body_schema_to_use:
764
781
  example_data = body_schema_to_use["example"]
765
782
  except KeyError:
@@ -777,18 +794,24 @@ def _generate_method_code(path, method, operation):
777
794
  # Adjust type_hint for file parameters for the docstring
778
795
  if detail.is_file:
779
796
  type_hint = "file (e.g., open('path/to/file', 'rb'))"
780
-
797
+
781
798
  arg_line = f" {arg_name} ({type_hint}): {desc}"
782
- if detail.example and not detail.is_file: # Don't show schema example for file inputs
799
+ if detail.example and not detail.is_file: # Don't show schema example for file inputs
783
800
  example_str = repr(detail.example)
784
801
  arg_line += f" Example: {example_str}."
785
802
  # Fallback for body parameters if no direct example was found
786
- elif not example_str and detail.where == "body" and example_data and isinstance(example_data, dict) and detail.identifier in example_data:
803
+ elif (
804
+ not example_str
805
+ and detail.where == "body"
806
+ and example_data
807
+ and isinstance(example_data, dict)
808
+ and detail.identifier in example_data
809
+ ):
787
810
  current_body_param_example = example_data[detail.identifier]
788
- if current_body_param_example is not None: # Ensure the extracted part is not None
811
+ if current_body_param_example is not None: # Ensure the extracted part is not None
789
812
  try:
790
813
  arg_line += f" Example: {repr(current_body_param_example)}."
791
- except Exception: # Fallback if repr fails
814
+ except Exception: # Fallback if repr fails
792
815
  arg_line += " Example: [Could not represent example]."
793
816
 
794
817
  args_doc_lines.append(arg_line)
@@ -797,19 +820,17 @@ def _generate_method_code(path, method, operation):
797
820
  args_doc_lines.append(
798
821
  f" {arg_name} (dict | None): Optional dictionary for an empty JSON request body (e.g., {{}})."
799
822
  )
800
- elif arg_name == raw_body_param_name:
823
+ elif arg_name == raw_body_param_name:
801
824
  raw_body_type_hint = "bytes"
802
825
  raw_body_desc = "Raw binary content for the request body."
803
826
  if selected_content_type and "text" in selected_content_type:
804
827
  raw_body_type_hint = "str"
805
828
  raw_body_desc = "Raw text content for the request body."
806
829
  elif selected_content_type and selected_content_type.startswith("image/"):
807
- raw_body_type_hint = "bytes (image data)"
808
- raw_body_desc = f"Raw image content ({selected_content_type}) for the request body."
809
- args_doc_lines.append(
810
- f" {arg_name} ({raw_body_type_hint} | None): {raw_body_desc}"
811
- )
812
-
830
+ raw_body_type_hint = "bytes (image data)"
831
+ raw_body_desc = f"Raw image content ({selected_content_type}) for the request body."
832
+ args_doc_lines.append(f" {arg_name} ({raw_body_type_hint} | None): {raw_body_desc}")
833
+
813
834
  if args_doc_lines:
814
835
  docstring_parts.append("\n".join(args_doc_lines))
815
836
 
@@ -825,7 +846,7 @@ def _generate_method_code(path, method, operation):
825
846
  raises_section_lines = [
826
847
  "Raises:",
827
848
  " HTTPError: Raised when the API request fails (e.g., non-2XX status code).",
828
- " JSONDecodeError: Raised if the response body cannot be parsed as JSON."
849
+ " JSONDecodeError: Raised if the response body cannot be parsed as JSON.",
829
850
  ]
830
851
  docstring_parts.append("\n".join(raises_section_lines))
831
852
 
@@ -853,7 +874,7 @@ def _generate_method_code(path, method, operation):
853
874
  else:
854
875
  signature = f" def {func_name}(self) -> {return_type}:"
855
876
 
856
- # --- Build Method Body ---
877
+ # --- Build Method Body ---
857
878
  # This section constructs the executable lines of code within the generated method.
858
879
  body_lines = []
859
880
 
@@ -861,10 +882,9 @@ def _generate_method_code(path, method, operation):
861
882
  for param in path_params:
862
883
  body_lines.append(f" if {param.name} is None:")
863
884
  body_lines.append(
864
- f' raise ValueError("Missing required parameter \'{param.identifier}\'.")' # Use original name in error, ensure quotes are balanced
885
+ f" raise ValueError(\"Missing required parameter '{param.identifier}'.\")" # Use original name in error, ensure quotes are balanced
865
886
  )
866
887
 
867
-
868
888
  if method_lower not in ["get", "delete"]:
869
889
  body_lines.append(" request_body_data = None")
870
890
 
@@ -874,7 +894,6 @@ def _generate_method_code(path, method, operation):
874
894
  if method_lower in ["post", "put"] and selected_content_type == "multipart/form-data":
875
895
  body_lines.append(" files_data = None")
876
896
 
877
-
878
897
  # --- Build Request Payload (request_body_data and files_data) ---
879
898
  # This section prepares the data to be sent in the request body,
880
899
  # differentiating between files and other data for multipart forms,
@@ -883,27 +902,30 @@ def _generate_method_code(path, method, operation):
883
902
  # This block will now overwrite the initial None values if a body is present.
884
903
  if is_array_body:
885
904
  # For array request bodies, use the array parameter directly
886
- array_arg_name = final_request_body_arg_names_for_signature[0] if final_request_body_arg_names_for_signature else "items_body" # Fallback
905
+ array_arg_name = (
906
+ final_request_body_arg_names_for_signature[0]
907
+ if final_request_body_arg_names_for_signature
908
+ else "items_body"
909
+ ) # Fallback
887
910
  body_lines.append(f" # Using array parameter '{array_arg_name}' directly as request body")
888
- body_lines.append(f" request_body_data = {array_arg_name}") # Use a neutral temp name
911
+ body_lines.append(f" request_body_data = {array_arg_name}") # Use a neutral temp name
889
912
  # files_data remains None
890
913
 
891
914
  elif selected_content_type == "multipart/form-data":
892
- body_lines.append(" request_body_data = {}") # For non-file form fields
893
- body_lines.append(" files_data = {}") # For file fields
894
- for b_param in body_params: # Iterate through ALIASED body_params
915
+ body_lines.append(" request_body_data = {}") # For non-file form fields
916
+ body_lines.append(" files_data = {}") # For file fields
917
+ for b_param in body_params: # Iterate through ALIASED body_params
895
918
  if b_param.is_file:
896
- body_lines.append(f" if {b_param.name} is not None:") # Check if file param is provided
919
+ body_lines.append(f" if {b_param.name} is not None:") # Check if file param is provided
897
920
  body_lines.append(f" files_data['{b_param.identifier}'] = {b_param.name}")
898
921
  else:
899
- body_lines.append(f" if {b_param.name} is not None:") # Check if form field is provided
922
+ body_lines.append(f" if {b_param.name} is not None:") # Check if form field is provided
900
923
  body_lines.append(f" request_body_data['{b_param.identifier}'] = {b_param.name}")
901
924
  body_lines.append(" files_data = {k: v for k, v in files_data.items() if v is not None}")
902
925
  # Ensure files_data is None if it's empty after filtering, as httpx expects None, not {}
903
926
  body_lines.append(" if not files_data: files_data = None")
904
927
 
905
-
906
- elif body_params: # Object request bodies (JSON, x-www-form-urlencoded) with specific parameters
928
+ elif body_params: # Object request bodies (JSON, x-www-form-urlencoded) with specific parameters
907
929
  body_lines.append(" request_body_data = {")
908
930
  for b_param in body_params:
909
931
  body_lines.append(f" '{b_param.identifier}': {b_param.name},")
@@ -911,13 +933,14 @@ def _generate_method_code(path, method, operation):
911
933
  body_lines.append(
912
934
  " request_body_data = {k: v for k, v in request_body_data.items() if v is not None}"
913
935
  )
914
-
915
- elif raw_body_param_name: # Raw content type (octet-stream, text, image)
936
+
937
+ elif raw_body_param_name: # Raw content type (octet-stream, text, image)
916
938
  body_lines.append(f" request_body_data = {raw_body_param_name}")
917
939
 
918
- elif has_empty_body and selected_content_type == "application/json": # Empty JSON object {}
919
- body_lines.append(f" request_body_data = {final_empty_body_param_name} if {final_empty_body_param_name} is not None else {{}}")
920
-
940
+ elif has_empty_body and selected_content_type == "application/json": # Empty JSON object {}
941
+ body_lines.append(
942
+ f" request_body_data = {final_empty_body_param_name} if {final_empty_body_param_name} is not None else {{}}"
943
+ )
921
944
 
922
945
  # --- Format URL and Query Parameters for Request ---
923
946
  url = _generate_url(path, path_params)
@@ -937,21 +960,20 @@ def _generate_method_code(path, method, operation):
937
960
 
938
961
  # --- Determine Final Content-Type for API Call (Obsolete Block, selected_content_type is used) ---
939
962
  # The following block for request_body_content_type is largely superseded by selected_content_type,
940
-
963
+
941
964
  # Use the selected_content_type determined by the new logic as the primary source of truth.
942
965
  final_content_type_for_api_call = selected_content_type if selected_content_type else "application/json"
943
966
 
944
967
  # --- Make HTTP Request ---
945
- # This section generates the actual HTTP call
968
+ # This section generates the actual HTTP call
946
969
  # using the prepared URL, query parameters, request body data, files, and content type.
947
970
 
948
-
949
971
  if method_lower == "get":
950
972
  body_lines.append(" response = self._get(url, params=query_params)")
951
973
  elif method_lower == "post":
952
974
  if selected_content_type == "multipart/form-data":
953
975
  body_lines.append(
954
- f" response = self._post(url, data=request_body_data, files=files_data, params=query_params, content_type='{final_content_type_for_api_call}')"
976
+ f" response = self._post(url, data=request_body_data, files=files_data, params=query_params, content_type='{final_content_type_for_api_call}')"
955
977
  )
956
978
  else:
957
979
  body_lines.append(
@@ -960,23 +982,18 @@ def _generate_method_code(path, method, operation):
960
982
  elif method_lower == "put":
961
983
  if selected_content_type == "multipart/form-data":
962
984
  body_lines.append(
963
- f" response = self._put(url, data=request_body_data, files=files_data, params=query_params, content_type='{final_content_type_for_api_call}')"
985
+ f" response = self._put(url, data=request_body_data, files=files_data, params=query_params, content_type='{final_content_type_for_api_call}')"
964
986
  )
965
987
  else:
966
988
  body_lines.append(
967
989
  f" response = self._put(url, data=request_body_data, params=query_params, content_type='{final_content_type_for_api_call}')"
968
990
  )
969
991
  elif method_lower == "patch":
970
-
971
- body_lines.append(
972
- " response = self._patch(url, data=request_body_data, params=query_params)"
973
- )
992
+ body_lines.append(" response = self._patch(url, data=request_body_data, params=query_params)")
974
993
  elif method_lower == "delete":
975
994
  body_lines.append(" response = self._delete(url, params=query_params)")
976
995
  else:
977
- body_lines.append(
978
- f" response = self._{method_lower}(url, data=request_body_data, params=query_params)"
979
- )
996
+ body_lines.append(f" response = self._{method_lower}(url, data=request_body_data, params=query_params)")
980
997
 
981
998
  # --- Handle Response ---
982
999
  body_lines.append(" response.raise_for_status()")
@@ -1145,4 +1162,4 @@ if __name__ == "__main__":
1145
1162
 
1146
1163
  schema = load_schema("openapi.yaml")
1147
1164
  code = generate_api_client(schema)
1148
- print(code)
1165
+ print(code)