Skip to content

Commit

Permalink
start creating application package
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkahan committed Apr 30, 2024
1 parent 5f6667d commit 47ce0f8
Show file tree
Hide file tree
Showing 15 changed files with 545 additions and 0 deletions.
16 changes: 16 additions & 0 deletions application/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource(name='pyproject', source='pyproject.toml')
file(name='readme', source='README.md')

files(sources=['tests/data/*'])

python_distribution(
name='vonage-application',
dependencies=[
':pyproject',
':readme',
'application/src/vonage_application',
],
provides=python_artifact(),
generate_setup=False,
repositories=['@pypi'],
)
2 changes: 2 additions & 0 deletions application/CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 1.0.0
- Initial upload
81 changes: 81 additions & 0 deletions application/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Vonage Users Package

This package contains the code to use Vonage's Application API in Python.

It includes methods for managing applications.

## Usage

It is recommended to use this as part of the main `vonage` package. The examples below assume you've created an instance of the `vonage.Vonage` class called `vonage_client`.

--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------
--------------

### List Users

With no custom options specified, this method will get the last 100 users. It returns a tuple consisting of a list of `UserSummary` objects and a string describing the cursor to the next page of results.

```python
from vonage_users import ListUsersRequest

users, _ = vonage_client.users.list_users()

# With options
params = ListUsersRequest(
page_size=10,
cursor=my_cursor,
order='desc',
)
users, next_cursor = vonage_client.users.list_users(params)
```

### Create a New User

```python
from vonage_users import User, Channels, SmsChannel
user_options = User(
name='my_user_name',
display_name='My User Name',
properties={'custom_key': 'custom_value'},
channels=Channels(sms=[SmsChannel(number='1234567890')]),
)
user = vonage_client.users.create_user(user_options)
```

### Get a User

```python
user = client.users.get_user('USR-87e3e6b0-cd7b-45ef-a0a7-bcd5566a672b')
user_as_dict = user.model_dump(exclude_none=True)
```

### Update a User
```python
from vonage_users import User, Channels, SmsChannel, WhatsappChannel
user_options = User(
name='my_user_name',
display_name='My User Name',
properties={'custom_key': 'custom_value'},
channels=Channels(sms=[SmsChannel(number='1234567890')], whatsapp=[WhatsappChannel(number='9876543210')]),
)
user = vonage_client.users.update_user(id, user_options)
```

### Delete a User

```python
vonage_client.users.delete_user(id)
```
29 changes: 29 additions & 0 deletions application/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[project]
name = 'vonage-application'
version = '1.0.0'
description = 'Vonage Users package'
readme = "README.md"
authors = [{ name = "Vonage", email = "devrel@vonage.com" }]
requires-python = ">=3.8"
dependencies = [
"vonage-http-client>=1.3.1",
"vonage-utils>=1.1.1",
"pydantic>=2.7.1",
]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: Apache Software License",
]

[project.urls]
homepage = "https://github.com/Vonage/vonage-python-sdk"

[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
1 change: 1 addition & 0 deletions application/src/vonage_application/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python_sources()
5 changes: 5 additions & 0 deletions application/src/vonage_application/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .application import Application

__all__ = [
'Application',
]
109 changes: 109 additions & 0 deletions application/src/vonage_application/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from typing import List, Optional, Tuple

from pydantic import validate_call
from vonage_http_client.http_client import HttpClient

from .common import User
from .requests import ApplicationOptions, ListApplicationsFilter
from .responses import ApplicationInfo


class Application:
"""Class containing methods for Vonage Application management."""

def __init__(self, http_client: HttpClient) -> None:
self._http_client = http_client
self._auth_type = 'basic'

@property
def http_client(self) -> HttpClient:
"""The HTTP client used to make requests to the Users API.
Returns:
HttpClient: The HTTP client used to make requests to the Users API.
"""
return self._http_client

@validate_call
def list_applications(
self, filter: ListApplicationsFilter = ListApplicationsFilter()
) -> Tuple[List[ApplicationInfo], Optional[str]]:
""""""
response = self._http_client.get(
self._http_client.api_host,
'/v2/applications',
filter.model_dump(exclude_none=True),
self._auth_type,
)

# applications_response = ListApplicationsResponse(**response)
# if applications_response.links.next is None:
# return applications_response.embedded.users, None

# parsed_url = urlparse(users_response.links.next.href)
# query_params = parse_qs(parsed_url.query)
# next_cursor = query_params.get('cursor', [None])[0]
# return users_response.embedded.users, next_cursor

@validate_call
def create_application(
self, params: Optional[ApplicationOptions] = None
) -> ApplicationData:
""".
.
"""
response = self._http_client.post(
self._http_client.api_host,
'/v2/applications',
params.model_dump(exclude_none=True) if params is not None else None,
self._auth_type,
)
return User(**response)

@validate_call
def get_user(self, id: str) -> User:
"""Get a user by ID.
Args:
id (str): The ID of the user to retrieve.
Returns:
User: The user object.
"""
response = self._http_client.get(
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
)
return User(**response)

@validate_call
def update_user(self, id: str, params: User) -> User:
"""Update a user.
Args:
id (str): The ID of the user to update.
params (User): The updated user object.
Returns:
User: The updated user object.
"""
response = self._http_client.patch(
self._http_client.api_host,
f'/v1/users/{id}',
params.model_dump(exclude_none=True),
self._auth_type,
)
return User(**response)

@validate_call
def delete_user(self, id: str) -> None:
"""Delete a user.
Args:
id (str): The ID of the user to delete.
Returns:
None
"""
self._http_client.delete(
self._http_client.api_host, f'/v1/users/{id}', None, self._auth_type
)
84 changes: 84 additions & 0 deletions application/src/vonage_application/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from typing import List, Optional

from pydantic import BaseModel, Field, model_validator
from vonage_utils.models import Link
from vonage_utils.types import PhoneNumber


class ResourceLink(BaseModel):
self: Link


class PstnChannel(BaseModel):
number: int


class SipChannel(BaseModel):
uri: str = Field(..., pattern=r'^(sip|sips):\+?([\w|:.\-@;,=%&]+)')
username: str = None
password: str = None


class VbcChannel(BaseModel):
extension: str


class WebsocketChannel(BaseModel):
uri: str = Field(pattern=r'^(ws|wss):\/\/[a-zA-Z0-9~#%@&-_?\/.,:;)(\]\[]*$')
content_type: Optional[str] = Field(
None, alias='content-type', pattern='^audio/l16;rate=(8000|16000)$'
)
headers: Optional[dict] = None


class SmsChannel(BaseModel):
number: PhoneNumber


class MmsChannel(BaseModel):
number: PhoneNumber


class WhatsappChannel(BaseModel):
number: PhoneNumber


class ViberChannel(BaseModel):
number: PhoneNumber


class MessengerChannel(BaseModel):
id: str


class Channels(BaseModel):
sms: Optional[List[SmsChannel]] = None
mms: Optional[List[MmsChannel]] = None
whatsapp: Optional[List[WhatsappChannel]] = None
viber: Optional[List[ViberChannel]] = None
messenger: Optional[List[MessengerChannel]] = None
pstn: Optional[List[PstnChannel]] = None
sip: Optional[List[SipChannel]] = None
websocket: Optional[List[WebsocketChannel]] = None
vbc: Optional[List[VbcChannel]] = None


class Properties(BaseModel):
custom_data: Optional[dict] = None


class User(BaseModel):
name: Optional[str] = None
display_name: Optional[str] = None
image_url: Optional[str] = None
channels: Optional[Channels] = None
properties: Optional[Properties] = None
links: Optional[ResourceLink] = Field(None, validation_alias='_links', exclude=True)
link: Optional[str] = None
id: Optional[str] = None

@model_validator(mode='after')
def get_link(self):
if self.links is not None:
self.link = self.links.self.href
return self
Loading

0 comments on commit 47ce0f8

Please sign in to comment.