diff --git a/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsOptions.cs b/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsOptions.cs index 1748335e0..6869a8e76 100644 --- a/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsOptions.cs +++ b/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsOptions.cs @@ -27,56 +27,56 @@ namespace Twilio.Rest.FlexApi.V1.Credential /// create public class CreateNewCredentialsOptions : IOptions { - - + + public string TestString { get; } - + public bool? TestBoolean { get; set; } - + public int? TestInteger { get; set; } - + public decimal? TestNumber { get; set; } - + public float? TestNumberFloat { get; set; } - + public double? TestNumberDouble { get; set; } - + public decimal? TestNumberInt32 { get; set; } - + public long? TestNumberInt64 { get; set; } - + public object TestObject { get; set; } - + public DateTime? TestDateTime { get; set; } - + public DateTime? TestDate { get; set; } - + public NewCredentialsResource.StatusEnum TestEnum { get; set; } - + public List TestObjectArray { get; set; } - + public object TestAnyType { get; set; } - + public List TestAnyArray { get; set; } - /// A comma-separated list of the permissions you will request from the users of this ConnectApp. Can include: `get-all` and `post-all`. + /// A comma-separated list of the permissions you will request from the users of this ConnectApp. Can include: `get-all` and `post-all`. public List Permissions { get; set; } - + public string SomeA2PThing { get; set; } @@ -90,7 +90,7 @@ public CreateNewCredentialsOptions(string testString) Permissions = new List(); } - + /// Generate the necessary parameters public List> GetParams() { @@ -167,7 +167,7 @@ public List> GetParams() return p; } - + } diff --git a/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsResource.cs b/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsResource.cs index 314fd0099..003fd8d59 100644 --- a/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsResource.cs +++ b/examples/csharp/src/Twilio/Rest/FlexApi/V1/Credential/NewCredentialsResource.cs @@ -29,9 +29,9 @@ namespace Twilio.Rest.FlexApi.V1.Credential { public class NewCredentialsResource : Resource { - - + + public sealed class StatusEnum : StringEnum { private StatusEnum(string value) : base(value) {} @@ -61,10 +61,10 @@ public static implicit operator PermissionsEnum(string value) public static readonly PermissionsEnum PostAll = new PermissionsEnum("post-all"); } - + private static Request BuildCreateRequest(CreateNewCredentialsOptions options, ITwilioRestClient client) { - + string path = "/v1/Credentials/AWS"; @@ -192,7 +192,7 @@ public static async System.Threading.Tasks.Task CreateAs } #endif - + /// /// Converts a JSON string into a NewCredentialsResource object /// @@ -226,20 +226,20 @@ public static string ToJson(object model) } } - - /// The account_sid + + /// The account_sid [JsonProperty("account_sid")] public string AccountSid { get; private set; } - /// The sid + /// The sid [JsonProperty("sid")] public string Sid { get; private set; } - /// The test_string + /// The test_string [JsonProperty("test_string")] public string TestString { get; private set; } - /// The test_integer + /// The test_integer [JsonProperty("test_integer")] public int? TestInteger { get; private set; } diff --git a/examples/python/examples/oneof_example.py b/examples/python/examples/oneof_example.py new file mode 100644 index 000000000..96891df5b --- /dev/null +++ b/examples/python/examples/oneof_example.py @@ -0,0 +1,247 @@ +""" +OneOf Example - Demonstrates how to use oneOf functionality in Twilio Python SDK + +This example shows how to work with APIs that accept multiple different object types +for the same parameter using the oneOf pattern. +""" + +from twilio.rest import Client +import os + +# Initialize the Twilio client +# Replace these with your actual credentials or set them as environment variables +account_sid = os.environ.get('TWILIO_ACCOUNT_SID', 'your_account_sid') +auth_token = os.environ.get('TWILIO_AUTH_TOKEN', 'your_auth_token') + +client = Client(account_sid, auth_token) + + +def example_1_create_cat(): + """ + Example 1: Create a pet using the Cat schema + + The Cat schema includes properties like account_sid, param1, and param2. + """ + print("\n=== Example 1: Creating a Pet with Cat Schema ===") + + # Create a Cat object with Cat-specific properties + cat = client.one_of.v1.pets.Cat({ + "account_sid": "AC1234567890abcdef", + "param1": "Persian", + "param2": "White", + }) + + # Inspect the cat object before sending + cat_dict = cat.to_dict() + print(f"Cat object: {cat_dict}") + + # Create the pet using the Cat schema + try: + pet = client.one_of.v1.pets.create(cat=cat) + print(f"✓ Successfully created pet with account_sid: {pet.account_sid}") + print(f" Param1: {pet.param1}") + print(f" Param2: {pet.param2}") + except Exception as e: + print(f"✗ Error creating pet: {e}") + + +def example_2_create_dog(): + """ + Example 2: Create a pet using the Dog schema + + The Dog schema includes different properties like type, name, and pack_size. + """ + print("\n=== Example 2: Creating a Pet with Dog Schema ===") + + # Create a Dog object with Dog-specific properties + dog = client.one_of.v1.pets.Dog({ + "type": "dog", + "name": "Bruno", + "pack_size": 5 + }) + + # Inspect the dog object + dog_dict = dog.to_dict() + print(f"Dog object: {dog_dict}") + + # Note: Currently the generated code accepts 'cat' parameter + # This demonstrates the object creation and serialization + print("✓ Dog object created and serialized successfully") + + +def example_3_nested_oneof(): + """ + Example 3: Working with nested oneOf objects + + This shows how a Cat can contain a Dog object (nested oneOf). + """ + print("\n=== Example 3: Nested OneOf Objects ===") + + # Create a nested Dog object + nested_dog = client.one_of.v1.pets.Dog({ + "type": "dog", + "name": "Rex", + "pack_size": 3 + }) + + # Create a Cat that contains the Dog + cat_with_dog = client.one_of.v1.pets.Cat({ + "account_sid": "AC1234567890abcdef", + "param1": "Siamese", + "param2": "Brown", + "dog": nested_dog, # Nested oneOf object + "object1": "extra_data_1", + "object2": "extra_data_2" + }) + + # Inspect the nested structure + cat_dict = cat_with_dog.to_dict() + print(f"Cat with nested Dog:") + print(f" account_sid: {cat_dict['account_sid']}") + print(f" param1: {cat_dict['param1']}") + print(f" param2: {cat_dict['param2']}") + print(f" nested dog: {cat_dict['dog']}") + print(f" object1: {cat_dict['object1']}") + print(f" object2: {cat_dict['object2']}") + + try: + pet = client.one_of.v1.pets.create(cat=cat_with_dog) + print("✓ Successfully created pet with nested oneOf object") + except Exception as e: + print(f"✗ Error creating pet: {e}") + + +def example_4_minimal_fields(): + """ + Example 4: Creating objects with minimal required fields + + OneOf objects support optional fields - you only need to provide the fields you need. + """ + print("\n=== Example 4: Minimal Fields ===") + + # Create a Cat with minimal fields + minimal_cat = client.one_of.v1.pets.Cat({ + "account_sid": "AC1234567890abcdef" + }) + + cat_dict = minimal_cat.to_dict() + print(f"Cat with minimal fields:") + print(f" account_sid: {cat_dict['account_sid']}") + print(f" param1: {cat_dict['param1']}") # Will be None + print(f" param2: {cat_dict['param2']}") # Will be None + print("✓ Minimal Cat object created successfully") + + +def example_5_dynamic_creation(): + """ + Example 5: Dynamic object creation based on type + + This shows a practical pattern for creating different types dynamically. + """ + print("\n=== Example 5: Dynamic Object Creation ===") + + def create_animal(animal_type, **properties): + """Helper function to create animals dynamically""" + if animal_type == 'cat': + return client.one_of.v1.pets.Cat(properties) + elif animal_type == 'dog': + return client.one_of.v1.pets.Dog(properties) + else: + raise ValueError(f"Unknown animal type: {animal_type}") + + # Create different animals dynamically + animals = [ + ('cat', {"account_sid": "AC111", "param1": "Maine Coon", "param2": "Large"}), + ('dog', {"type": "dog", "name": "Max", "pack_size": 8}), + ('cat', {"account_sid": "AC222", "param1": "Tabby", "param2": "Orange"}), + ] + + for animal_type, properties in animals: + animal = create_animal(animal_type, **properties) + animal_dict = animal.to_dict() + print(f"✓ Created {animal_type}: {animal_dict}") + + +def example_6_error_handling(): + """ + Example 6: Error handling with oneOf objects + """ + print("\n=== Example 6: Error Handling ===") + + try: + # Attempt to create a pet + cat = client.one_of.v1.pets.Cat({ + "account_sid": "AC_TEST", + "param1": "test_value" + }) + + # This would make an actual API call + # pet = client.one_of.v1.pets.create(cat=cat) + + print("✓ Object created successfully (API call not made in this example)") + + except Exception as e: + print(f"✗ Error occurred: {type(e).__name__}: {e}") + + +async def example_7_async_usage(): + """ + Example 7: Async usage of oneOf functionality + + This example requires async context to run. + """ + print("\n=== Example 7: Async Usage ===") + + from twilio.http.async_http_client import AsyncTwilioHttpClient + + # Create async client + http_client = AsyncTwilioHttpClient() + async_client = Client(account_sid, auth_token, http_client=http_client) + + try: + # Create a Cat object + cat = async_client.one_of.v1.pets.Cat({ + "account_sid": "AC1234567890abcdef", + "param1": "Russian Blue", + "param2": "Gray" + }) + + # This would make an async API call + # pet = await async_client.one_of.v1.pets.create_async(cat=cat) + + print("✓ Async object created successfully (API call not made in this example)") + + finally: + # Clean up async resources + await http_client.session.close() + + +def main(): + """ + Run all examples + """ + print("=" * 60) + print("Twilio Python SDK - OneOf Functionality Examples") + print("=" * 60) + + # Run synchronous examples + example_1_create_cat() + example_2_create_dog() + example_3_nested_oneof() + example_4_minimal_fields() + example_5_dynamic_creation() + example_6_error_handling() + + # Async example requires event loop + print("\n=== Note on Async Example ===") + print("To run the async example, use:") + print(" import asyncio") + print(" asyncio.run(example_7_async_usage())") + + print("\n" + "=" * 60) + print("Examples completed!") + print("=" * 60) + + +if __name__ == "__main__": + main() diff --git a/examples/python/tests/unit/one_of_test.py b/examples/python/tests/unit/one_of_test.py new file mode 100644 index 000000000..e210ada97 --- /dev/null +++ b/examples/python/tests/unit/one_of_test.py @@ -0,0 +1,212 @@ +import unittest +from unittest.mock import patch, ANY +from twilio.rest import Client +from twilio.http.async_http_client import AsyncTwilioHttpClient +from twilio.http.response import Response + + +@patch("twilio.http.http_client.TwilioHttpClient.request") +class OneOfTests(unittest.TestCase): + def setUp(self) -> None: + self.sid = "AC12345678123456781234567812345678" + self.auth = "CR12345678123456781234567812345678" + self.client = Client(self.sid, self.auth) + self.generic_request_args = { + "params": ANY, + "data": ANY, + "headers": ANY, + "auth": ANY, + "timeout": ANY, + "allow_redirects": ANY, + } + + def test_create_pet_with_cat(self, mock_request): + """Test creating a pet with Cat oneOf option""" + mock_request.return_value = Response( + 200, '{"account_sid": "AC123", "param1": "value1", "param2": "value2"}' + ) + + # Create a Cat object using the inner class + cat = self.client.one_of.v1.pets.Cat( + { + "account_sid": "AC123", + "param1": "value1", + "param2": "value2", + } + ) + + # Create pet with Cat + result = self.client.one_of.v1.pets.create(cat=cat) + + # Verify the request was made correctly + request_args = self.generic_request_args + request_args["data"] = { + "account_sid": "AC123", + "param1": "value1", + "param2": "value2", + } + + mock_request.assert_called_once_with( + "POST", "http://oneOf.twilio.com/v1/pets", **request_args + ) + + # Verify the response + self.assertEqual(result.account_sid, "AC123") + self.assertEqual(result.param1, "value1") + self.assertEqual(result.param2, "value2") + + def test_create_pet_with_dog(self, mock_request): + """Test creating a pet with Dog oneOf option""" + mock_request.return_value = Response( + 200, '{"type": "dog", "name": "Bruno", "pack_size": 5}' + ) + + # Create a Dog object using the inner class + dog = self.client.one_of.v1.pets.Dog( + {"type": "dog", "name": "Bruno", "pack_size": 5} + ) + + # Note: Currently the generated code only accepts 'cat' parameter + # This test documents the expected behavior when full oneOf support is added + # For now, we'll test with cat parameter + cat = self.client.one_of.v1.pets.Cat( + {"type": "dog", "name": "Bruno", "pack_size": 5} + ) + + result = self.client.one_of.v1.pets.create(cat=cat) + + request_args = self.generic_request_args + request_args["data"] = {"type": "dog", "name": "Bruno", "pack_size": 5} + + mock_request.assert_called_once() + + def test_cat_to_dict(self, mock_request): + """Test Cat object serialization""" + cat = self.client.one_of.v1.pets.Cat( + { + "account_sid": "AC123", + "param1": "value1", + "param2": "value2", + "dog": None, + "object1": "obj1", + "object2": "obj2", + } + ) + + cat_dict = cat.to_dict() + + self.assertEqual(cat_dict["account_sid"], "AC123") + self.assertEqual(cat_dict["param1"], "value1") + self.assertEqual(cat_dict["param2"], "value2") + self.assertEqual(cat_dict["object1"], "obj1") + self.assertEqual(cat_dict["object2"], "obj2") + self.assertIsNone(cat_dict["dog"]) + + def test_dog_to_dict(self, mock_request): + """Test Dog object serialization""" + dog = self.client.one_of.v1.pets.Dog( + {"type": "dog", "name": "Bruno", "pack_size": 5} + ) + + dog_dict = dog.to_dict() + + self.assertEqual(dog_dict["type"], "dog") + self.assertEqual(dog_dict["name"], "Bruno") + self.assertEqual(dog_dict["pack_size"], 5) + + def test_nested_oneof_with_dog_in_cat(self, mock_request): + """Test Cat with nested Dog object (tests nested oneOf)""" + mock_request.return_value = Response( + 200, + '{"account_sid": "AC123", "param1": "value1", "dog": {"type": "dog", "name": "Rex", "pack_size": 3}}', + ) + + # Create a nested Dog object + dog = self.client.one_of.v1.pets.Dog( + {"type": "dog", "name": "Rex", "pack_size": 3} + ) + + # Create Cat with nested Dog + cat = self.client.one_of.v1.pets.Cat( + {"account_sid": "AC123", "param1": "value1", "dog": dog} + ) + + result = self.client.one_of.v1.pets.create(cat=cat) + + self.assertEqual(result.account_sid, "AC123") + + +@patch("twilio.http.async_http_client.AsyncTwilioHttpClient.request") +class AsyncOneOfTests(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self) -> None: + self.sid = "AC12345678123456781234567812345678" + self.auth = "CR12345678123456781234567812345678" + self.http_client = AsyncTwilioHttpClient() + self.client = Client(self.sid, self.auth, http_client=self.http_client) + self.generic_request_args = { + "params": ANY, + "data": ANY, + "headers": ANY, + "auth": ANY, + "timeout": ANY, + "allow_redirects": ANY, + } + + async def asyncTearDown(self) -> None: + await self.http_client.session.close() + + async def test_async_create_pet_with_cat(self, mock_request): + """Test async creating a pet with Cat oneOf option""" + mock_request.return_value = Response( + 200, '{"account_sid": "AC123", "param1": "value1", "param2": "value2"}' + ) + + # Create a Cat object using the inner class + cat = self.client.one_of.v1.pets.Cat( + { + "account_sid": "AC123", + "param1": "value1", + "param2": "value2", + } + ) + + # Create pet with Cat asynchronously + result = await self.client.one_of.v1.pets.create_async(cat=cat) + + # Verify the request was made correctly + request_args = self.generic_request_args + request_args["data"] = { + "account_sid": "AC123", + "param1": "value1", + "param2": "value2", + } + + mock_request.assert_called_once_with( + "POST", "http://oneOf.twilio.com/v1/pets", **request_args + ) + + # Verify the response + self.assertEqual(result.account_sid, "AC123") + self.assertEqual(result.param1, "value1") + self.assertEqual(result.param2, "value2") + + async def test_async_create_pet_with_dog(self, mock_request): + """Test async creating a pet with Dog oneOf option""" + mock_request.return_value = Response( + 200, '{"type": "dog", "name": "Bruno", "pack_size": 5}' + ) + + # Create a Dog object + dog = self.client.one_of.v1.pets.Dog( + {"type": "dog", "name": "Bruno", "pack_size": 5} + ) + + # Note: Currently the generated code only accepts 'cat' parameter + # This test documents the expected behavior when full oneOf support is added + cat = self.client.one_of.v1.pets.Cat( + {"type": "dog", "name": "Bruno", "pack_size": 5} + ) + + result = await self.client.one_of.v1.pets.create_async(cat=cat) + + mock_request.assert_called_once() diff --git a/examples/python/twilio/rest/one_of/v1/__init__.py b/examples/python/twilio/rest/one_of/v1/__init__.py new file mode 100644 index 000000000..40f7c3c3f --- /dev/null +++ b/examples/python/twilio/rest/one_of/v1/__init__.py @@ -0,0 +1,43 @@ +r""" + This code was generated by + ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __ + | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/ + | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \ + + Number Pool Service + This service is an entry point for all Number Pool CRUD requests. + + NOTE: This class is auto generated by OpenAPI Generator. + https://openapi-generator.tech + Do not edit the class manually. +""" + +from typing import Optional +from twilio.base.version import Version +from twilio.base.domain import Domain +from twilio.rest.one_of.v1.pet import PetList + + +class V1(Version): + + def __init__(self, domain: Domain): + """ + Initialize the V1 version of OneOf + + :param domain: The Twilio.one_of domain + """ + super().__init__(domain, "v1") + self._pets: Optional[PetList] = None + + @property + def pets(self) -> PetList: + if self._pets is None: + self._pets = PetList(self) + return self._pets + + def __repr__(self) -> str: + """ + Provide a friendly representation + :returns: Machine friendly representation + """ + return "" diff --git a/examples/python/twilio/rest/one_of/v1/pet.py b/examples/python/twilio/rest/one_of/v1/pet.py new file mode 100644 index 000000000..7bbf3ff27 --- /dev/null +++ b/examples/python/twilio/rest/one_of/v1/pet.py @@ -0,0 +1,246 @@ +r""" + This code was generated by + ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __ + | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/ + | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \ + + Number Pool Service + This service is an entry point for all Number Pool CRUD requests. + + NOTE: This class is auto generated by OpenAPI Generator. + https://openapi-generator.tech + Do not edit the class manually. +""" + + +from datetime import date, datetime +from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator +from twilio.base import deserialize, serialize, values + +from twilio.base.instance_resource import InstanceResource +from twilio.base.list_resource import ListResource +from twilio.base.version import Version + + + +class PetInstance(InstanceResource): + + class Cat(object): + """ + :ivar account_sid: + :ivar param1: + :ivar param2: + :ivar dog: + :ivar object1: + :ivar object2: + """ + + def __init__(self, payload: Dict[str, Any]): + + + self.account_sid: Optional[str] = payload.get("account_sid") + self.param1: Optional[str] = payload.get("param1") + self.param2: Optional[str] = payload.get("param2") + self.dog: Optional[PetList.Dog] = payload.get("dog") + self.object1: Optional[str] = payload.get("object1") + self.object2: Optional[str] = payload.get("object2") + + def to_dict(self): + return { + + "account_sid": self.account_sid, + "param1": self.param1, + "param2": self.param2, + "dog": self.dog.to_dict() if self.dog is not None else None , + "object1": self.object1, + "object2": self.object2, + } + + class Dog(object): + """ + :ivar type: + :ivar name: + :ivar pack_size: + """ + + def __init__(self, payload: Dict[str, Any]): + + + self.type: Optional["PetInstance.str"] = payload.get("type") + self.name: Optional[str] = payload.get("name") + self.pack_size: Optional[int] = payload.get("pack_size") + + def to_dict(self): + return { + + "type": self.type, + "name": self.name, + "pack_size": self.pack_size, + } + + + + """ + :ivar account_sid: + :ivar param1: + :ivar param2: + :ivar dog: + :ivar object1: + :ivar object2: + """ + + def __init__(self, version: Version, payload: Dict[str, Any]): + super().__init__(version) + + + self.account_sid: Optional[str] = payload.get("account_sid") + self.param1: Optional[str] = payload.get("param1") + self.param2: Optional[str] = payload.get("param2") + self.dog: Optional[PetList.str] = payload.get("dog") + self.object1: Optional[str] = payload.get("object1") + self.object2: Optional[str] = payload.get("object2") + + + + + def __repr__(self) -> str: + """ + Provide a friendly representation + + :returns: Machine friendly representation + """ + + return '' + + + + +class PetList(ListResource): + + class Cat(object): + """ + :ivar account_sid: + :ivar param1: + :ivar param2: + :ivar dog: + :ivar object1: + :ivar object2: + """ + + def __init__(self, payload: Dict[str, Any]): + + + self.account_sid: Optional[str] = payload.get("account_sid") + self.param1: Optional[str] = payload.get("param1") + self.param2: Optional[str] = payload.get("param2") + self.dog: Optional[PetList.Dog] = payload.get("dog") + self.object1: Optional[str] = payload.get("object1") + self.object2: Optional[str] = payload.get("object2") + + def to_dict(self): + return { + + "account_sid": self.account_sid, + "param1": self.param1, + "param2": self.param2, + "dog": self.dog.to_dict() if self.dog is not None else None , + "object1": self.object1, + "object2": self.object2, + } + + class Dog(object): + """ + :ivar type: + :ivar name: + :ivar pack_size: + """ + + def __init__(self, payload: Dict[str, Any]): + + + self.type: Optional["PetInstance.str"] = payload.get("type") + self.name: Optional[str] = payload.get("name") + self.pack_size: Optional[int] = payload.get("pack_size") + + def to_dict(self): + return { + + "type": self.type, + "name": self.name, + "pack_size": self.pack_size, + } + + + def __init__(self, version: Version): + """ + Initialize the PetList + + :param version: Version that contains the resource + + """ + super().__init__(version) + + + self._uri = '/pets' + + + + def create(self, cat: Cat) -> PetInstance: + """ + Create the PetInstance + + :param cat: + + :returns: The created PetInstance + """ + data = cat.to_dict() + + headers = values.of({ + 'Content-Type': 'application/x-www-form-urlencoded' + }) + + headers["Content-Type"] = "application/json" + + + headers["Accept"] = "application/json" + + + payload = self._version.create(method='POST', uri=self._uri, data=data, headers=headers) + + return PetInstance(self._version, payload) + + async def create_async(self, cat: Cat) -> PetInstance: + """ + Asynchronously create the PetInstance + + :param cat: + + :returns: The created PetInstance + """ + data = cat.to_dict() + + headers = values.of({ + 'Content-Type': 'application/x-www-form-urlencoded' + }) + + headers["Content-Type"] = "application/json" + + + headers["Accept"] = "application/json" + + + payload = await self._version.create_async(method='POST', uri=self._uri, data=data, headers=headers) + + return PetInstance(self._version, payload) + + + + + def __repr__(self) -> str: + """ + Provide a friendly representation + + :returns: Machine friendly representation + """ + return '' +