Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update openapi #4

Merged
merged 21 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
name: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: '3.10'
- name: Install poetry
run: pip install poetry
- name: Install project dependencies
Expand All @@ -21,12 +21,20 @@ jobs:
run: poetry run lint
- name: Check format
run: poetry run format_check
- name: Type checker
run: poetry run pyright

test:
runs-on: ubuntu-latest
name: test
steps:
- uses: actions/checkout@v4
- run: docker compose -f docker-compose-test.yaml up test --exit-code-from test
- run: docker compose -f docker-compose-test.yaml down
- run: docker compose -f docker-compose-test.yaml up examples --exit-code-from examples
runs-on: ubuntu-latest
name: test
steps:
- uses: actions/checkout@v4

- name: Log in to GitHub Container Registry
run: echo "${{ secrets.PACKAGE_ACCESS_TOKEN }}" | docker login ghcr.io -u USERNAME --password-stdin

- name: Run tests
run: docker compose -f docker-compose-test.yaml up test --exit-code-from test

- name: Tear down test containers
run: docker compose -f docker-compose-test.yaml down
15 changes: 15 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: publish package

on:
push:
tags:
- "v*.*.*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and publish to pypi
uses: JRubics/[email protected]
with:
pypi_token: ${{ secrets.PYPI_TOKEN }}
90 changes: 26 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

# Fishjam Python Server SDK

[![CircleCI](https://dl.circleci.com/status-badge/img/gh/fishjam-cloud/python-server-sdk/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/fishjam-cloud/python-server-sdk/tree/main)

Python server SDK for the [Fishjam Media Server](https://github.com/fishjam-cloud/fishjam).
Python server SDK for the [Fishjam Cloud](https://fishjam.io/).

Read the docs [here](https://fishjam-cloud.github.io/python-server-sdk)

Expand All @@ -16,114 +14,78 @@ pip install fishjam-server-sdk

## Usage

The SDK exports two main classes for interacting with Fishjam server: `RoomApi` and `Notifier`.
The SDK exports two main classes for interacting with Fishjam server:
`FishjamClient` and `FishjamNotifier`.

`RoomApi` wraps http REST api calls, while `Notifier` is responsible for receiving real-time updates from the server.
`FishjamClient` wraps http REST api calls, while `FishjamNotifier` is responsible for receiving real-time updates from the server.

#### RoomApi
#### FishjamClient

Create a `RoomApi` instance, providing the fishjam server address and api token
Create a `FishjamClient` instance, providing the fishjam server address and api token

```python
from fishjam import RoomApi
from fishjam import FishjamClient

room_api = RoomApi(server_address="localhost:5002", server_api_token="development")
fishjam_client = FishjamClient(fishjam_url="localhost:5002", management_token="development")
```

You can use it to interact with Fishjam, manage rooms, peers and components
You can use it to interact with Fishjam Cloud to manage rooms and peers

```python
# Create a room
fishjam_address, room = room_api.create_room(video_codec="h264", webhook_url="http://localhost:5000/webhook")
# '127.0.0.1:5002', Room(components=[], config=RoomConfig(max_peers=None, video_codec=<RoomConfigVideoCodec.H264: 'h264'>, webhook_url='http://localhost:5000/webhook'), id='1d905478-ccfc-44d6-a6e7-8ccb1b38d955', peers=[])

# Add peer to the room
from fishjam import PeerOptionsWebRTC
options = RoomOptions(video_codec="h264", webhook_url="http://localhost:5000/webhook")
room = fishjam_client.create_room(options=options)

peer_token, peer_webrtc = room_api.add_peer(room.id, options=PeerOptionsWebRTC())
# 'M8TUGhj-L11KpyG-2zBPIo', Peer(id='b1232c7e-c969-4450-acdf-ea24f3cdd7f6', status=<PeerStatus.DISCONNECTED: 'disconnected'>, type='webrtc')
# Room(components=[], config=RoomConfig(max_peers=None, video_codec=<RoomConfigVideoCodec.H264: 'h264'>, webhook_url='http://localhost:5000/webhook'), id='1d905478-ccfc-44d6-a6e7-8ccb1b38d955', peers=[])

# Add component to the room
from fishjam import ComponentOptionsHLS
# Add peer to the room
peer, token = fishjam_client.create_peer(room.id)

component_hls = room_api.add_component(room.id, options=ComponentOptionsHLS())
# ComponentHLS(id='5f062447-a9f7-45ed-8d1b-511f77dc78ae', properties=ComponentPropertiesHLS(low_latency=False, persistent=False, playable=False, subscribe_mode=<ComponentPropertiesHLSSubscribeMode.AUTO: 'auto'>, target_window_duration=None), type='hls')
# Peer(id='b1232c7e-c969-4450-acdf-ea24f3cdd7f6', status=<PeerStatus.DISCONNECTED: 'disconnected'>, type='webrtc'), 'M8TUGhj-L11KpyG-2zBPIo'
```

All methods in `RoomApi` may raise one of the exceptions deriving from `fishjam.errors.HTTPError`. They are defined in
`fishjam.errors`.
All methods in `FishjamClient` may raise one of the exceptions deriving from `fishjam.errors.HTTPError`. They are defined in `fishjam.errors`.

#### Notifier
#### FishjamNotifier

Notifier allows for receiving real-time updates from the Fishjam Server.
FishjamNotifier allows for receiving real-time updates from the Fishjam Server.

You can read more about notifications in the
[Fishjam Docs](https://fishjam-cloud.github.io/fishjam-docs/next/getting_started/notifications).

Create `Notifier` instance
Create `FishjamNotifier` instance

```python
from fishjam import Notifier
from fishjam import FishjamNotifier

notifier = Notifier(server_address='localhost:5002', server_api_token='development')
fishjam_notifier = FishjamNotifier(fishjam_url='localhost:5002', management_token='development')
```

Then define handlers for incoming messages

Then define a handler for incoming messages
```python
@notifier.on_server_notification
def handle_notification(server_notification):
print(f'Received a notification: {server_notification}')

@notifier.on_metrics
def handle_metrics(metrics_report):
print(f'Received WebRTC metrics: {metrics_report}')
```

After that you can start the notifier

```python
async def test_notifier():
notifier_task = asyncio.create_task(notifier.connect())
notifier_task = asyncio.create_task(fishjam_notifier.connect())

# Wait for notifier to be ready to receive messages
await notifier.wait_ready()
await fishjam_notifier.wait_ready()

# Create a room to trigger a server notification
room_api = RoomApi()
room_api.create_room()
fishjam_client = FishjamClient()
fishjam_client.create_room()

await notifier_task

asyncio.run(test_notifier())

# Received a notification: ServerMessageRoomCreated(room_id='69a3fd1a-6a4d-47bc-ae54-0c72b0d05e29')
# Received WebRTC metrics: ServerMessageMetricsReport(metrics='{}')
```

#### Cluster of Fishjams

The cluster of fishjams has got embedded load balancer, which means that a new room will be created on fishjam with the
least usage. At the moment to modify this specific room you must communicate with the fishjam on which this room was
created.

```python
room_api = RoomApi(server_address='localhost:5002')

# Create a room to trigger a server notification with h264 as a codec,
# that allow to use HLS.
address, room = room_api.create_room(video_codec="h264")

# Create new room api with returned fishjam address as a room could be
# created on a different fishjam instance
# (if you communicate with a cluster of fishjams)
new_room_api = RoomApi(server_address=address)

# Add HLS component with manual subscribe mode, we use here `new_room_api` as we are sure that this API refers to the fishjam on which this room was created.
_hls_component = new_room_api.add_component(
room.id,
ComponentOptionsHLS(subscribe_mode=ComponentOptionsHLSSubscribeMode.MANUAL),
)
```

## Testing
Expand Down
6 changes: 3 additions & 3 deletions docker-compose-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
FJ_PORT: 5002
FJ_SECRET_KEY_BASE: "super-secret-key"
FJ_SIP_IP: "127.0.0.1"
FJ_COMPONENTS_USED: rtsp file hls recording sip
FJ_COMPONENTS_USED: "rtsp file hls recording sip"
ports:
- "5002:5002"
- "49999:49999"
Expand All @@ -30,7 +30,7 @@ services:

test:
container_name: test
image: "cimg/python:${PYTHON_VERSION:-3.8}"
image: "cimg/python:${PYTHON_VERSION:-3.10}"
command: sh -c "cd /app && \ poetry config virtualenvs.in-project false && \ poetry install --no-ansi && \ poetry run pytest -s"
environment:
DOCKER_TEST: "TRUE"
Expand All @@ -44,7 +44,7 @@ services:

examples:
container_name: examples
image: "cimg/python:${PYTHON_VERSION:-3.8}"
image: "cimg/python:${PYTHON_VERSION:-3.10}"
command: sh -c "cd /app && \ poetry config virtualenvs.in-project false && \ poetry cache clear pypi --all && \ poetry install --no-ansi && \ poetry run examples"
environment:
DOCKER_TEST: "TRUE"
Expand Down
81 changes: 0 additions & 81 deletions examples/mini_tutorial.py

This file was deleted.

Empty file.
15 changes: 15 additions & 0 deletions examples/room-manager/arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import argparse


def parse_arguments():
parser = argparse.ArgumentParser(description="Room Manager")

parser.add_argument("--port", type=int, default=5002)
parser.add_argument("--peerless_purge_timeout", type=int, default=None)
parser.add_argument("--webhook_url", type=str, default=None)
parser.add_argument("--enable_simulcast", type=str, default=True)
parser.add_argument("--max_peers", type=str, default=None)
parser.add_argument("--fishjam_url", type=str, default="http://localhost:5002")
parser.add_argument("--management_token", type=str, default="development")

return parser.parse_args()
20 changes: 20 additions & 0 deletions examples/room-manager/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import logging

from flask import Flask

from .arguments import parse_arguments
from .room_service import RoomService
from .routes import setup_routes

app = Flask(__name__)
app.logger.setLevel(logging.INFO)


if __name__ == "__main__":
args = parse_arguments()

room_service = RoomService(args, app.logger)

setup_routes(app, room_service)

app.run()
Loading