add: demo server and client
This commit is contained in:
192
README.md
192
README.md
@@ -1,4 +1,4 @@
|
||||
*/# PeerNet -- peer-to-peer communication without the network
|
||||
# PeerNet -- peer-to-peer communication without the network
|
||||
|
||||
PeerNet is a protocol and server software which let clients communicate directly with each other without required a lot of configuration or system permissions. It leverages WebRTC to create data channels between peers, and uses a simple protocol to let clients advertise services for other clients to connect with. Initially developed as an attempt to simplify a home security system, the reference client implementations offer:
|
||||
|
||||
@@ -19,79 +19,147 @@ One minor goal in this API design is to minimize the number of messages that nee
|
||||
|
||||
Sample server flow:
|
||||
|
||||
```pyton
|
||||
import requests
|
||||
1. Server creates an auth token; this is secret, and is used to restrict actions related to the server such as updating/deleting it, or listing pending knocks
|
||||
2. Server send a POST to /v1/servers with the server object, including a list of services offered
|
||||
3. Server begins polling /v1/servers/{server}/services/{service}/knocks for client attempts to connect
|
||||
4. When a knock is recieved, a worker should be spawned to handle the connection
|
||||
|
||||
url = 'https://myserver.local'
|
||||
When a client connects, the standard WebRTC negotation commences. Restating from [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity#session_descriptions):
|
||||
|
||||
1. Peer connection is created in client (caller, in WebRTC parliance)
|
||||
2. Attach channels to it (i.e., a data channel)
|
||||
3. Client creates an offer; they set the 'local description' to the offer
|
||||
4. Client sends request to signaling server (peernet server)
|
||||
5. The peer recieves the request and sets remote description to the offer
|
||||
6. The peer creates an answer and sets it to 'local description'
|
||||
7. The peer sends the answer to the signaling server (peernet server)
|
||||
8. Client recieves the answer and sets it as remote description
|
||||
|
||||
In steps 3 and 6, the client and peer indicate a STUN/TURN server and begin generating ICE candidates. This is where the mgaic of bridging firewalls happens. The candidates will trickle from each system, and must be passed through the signaling server to the other system. The hope is that eventually both the client and peer find an ICE candidate they can use to exchange data without a middle man.
|
||||
|
||||
Once the ICE negotation has completed, data can flow according to the service protocol. Using the Python aiortc library, this might look like:
|
||||
|
||||
```
|
||||
async def handle_offer(knock, peernetClient):
|
||||
pc = RTCPeerConnection()
|
||||
|
||||
# Define our handlers
|
||||
done = False
|
||||
|
||||
@pc.on("datachannel")
|
||||
def on_datachannel(channel):
|
||||
@channel.on("message")
|
||||
def on_message(message):
|
||||
# Process the message, and send a response
|
||||
channel.send("pong" + message[4:])
|
||||
|
||||
@pc.on("connectionstatechange")
|
||||
async def on_connectionstatechange():
|
||||
if pc.connectionState == "failed":
|
||||
done = True
|
||||
await pc.close()
|
||||
|
||||
@pc.on("icecandidate")
|
||||
async def on_icecandidate(candidate):
|
||||
peernetClient.post("/v1/sessions/{knock.offer.name}/candidates", {
|
||||
"candidate": candidate_to_sdp(obj),
|
||||
"sdpMid": obj.sdpMid,
|
||||
"sdpLineIndex": obj.sdpMLineIndex,
|
||||
})
|
||||
|
||||
|
||||
# Add the remote offer
|
||||
offer = RTCSessionDescription(sdp=knock.offer.sdp, type=knock.offer.sdpType)
|
||||
await pc.setRemoteDescription(offer)
|
||||
# Create an answer
|
||||
answer = await pc.createAnswer()
|
||||
await pc.setLocalDescription(answer)
|
||||
# Send the answer
|
||||
session_id = uuid.new()
|
||||
knock.answer = {
|
||||
"name": session_id,
|
||||
"sdp": answer.sdp,
|
||||
"sdpType", answer.sdptype"
|
||||
}
|
||||
peernetClient.patch(knock.name, knock)
|
||||
|
||||
while not done:
|
||||
candidates = peernetClient.get("/v1/sessions/{session_id}/claim/candidates")
|
||||
for candidate in candidates:
|
||||
ice_candidate = candidate_from_sdp(candidate.candidate)
|
||||
ice_candidate.sdpMid = candidate.sdpMid
|
||||
ice_candidate.sdpMLineIndex = candidate.sdpLineIndex
|
||||
await pc.addIceCandidate(candidate)
|
||||
|
||||
response = requests.post(url + '/server', '''
|
||||
{
|
||||
"unique_id": "
|
||||
}
|
||||
''')
|
||||
```
|
||||
|
||||
The protocol is define below in Protobuf, but is also availabe [here] in OpenAPI format.
|
||||
|
||||
```proto2
|
||||
syntax = "proto2";
|
||||
package peernet
|
||||
server.py
|
||||
```pyton
|
||||
import requests
|
||||
import instance.serve
|
||||
import uuid
|
||||
|
||||
service PeerNetService {
|
||||
rpc CreateRoom(CreateRoomRequest) returns (CreateRoomResponse);
|
||||
rpc DeleteRoom(DeleteRoomRequest) return (DeleteRoomResponse);
|
||||
url = 'https://myserver.local/v1'
|
||||
auth_token = uuid.uuid4()
|
||||
|
||||
rpc CreateServer(CreateServerRequest) returns (CreateServerResponse);
|
||||
rpc DeleteServer(DeleteServerRequest) returns (DeleteServerResponse);
|
||||
rpc ListServers(ListServersRequest) returns (ListServersResponse);
|
||||
|
||||
rpc CreateService(CreateServiceRequest) returns (CreateServiceResponse);
|
||||
rpc DeleteService(DeleteServiceRequest) returns (DeleteServiceResponse);
|
||||
rpc UpdateService(UpdateServiceRequest) returns (UpdateServiceResponse);
|
||||
|
||||
rpc CreateKnock(CreateKnockRequest) returns (CreateKnockResponse);
|
||||
rpc DeleteKnock(DeleteKnockRequest) returns (DeleteKnockResponse);
|
||||
rpc GetKnock(GetKnockRequest) returns (Knock);
|
||||
rpc ListKnocks(ListKnocksRequest) returns (ListKnocksResponse);
|
||||
# This call creates a few things as a side effect:
|
||||
# 1. The rooms 'the-good-place' and 'the-bad-place'
|
||||
# 2. A server with the display_name "Chidi"
|
||||
# 3. A service beloning to that server
|
||||
create_server_response = requests.post(url + '/servers', '''
|
||||
{
|
||||
"unique_id": "my-public-name",
|
||||
"rooms": [
|
||||
"the-good-place",
|
||||
"the-bad-place",
|
||||
],
|
||||
"auth_token": %s
|
||||
"display_name": "Chidi",
|
||||
"services": [
|
||||
{
|
||||
"protocol": "peernet.http",
|
||||
"version": "1.1",
|
||||
},
|
||||
],
|
||||
}
|
||||
''' % auth_token)
|
||||
|
||||
message Room {
|
||||
string unique_id = 1;
|
||||
string display_name = 2;
|
||||
}
|
||||
# Response contains a token we use to authorize ourselves
|
||||
auth_header = {"Authorization": auth_token}
|
||||
|
||||
message Server {
|
||||
string unique_id = 1;
|
||||
# Poll for clients, and spin off a helper when one tries to connect
|
||||
while True:
|
||||
claim_knocks_response = request.get(
|
||||
url + "/servers/%s/claim_knocks" % create_server_response.unique_id,
|
||||
# The filter lets us ignore service we don't support
|
||||
'''
|
||||
"filter": "service.name=\"peernet.http\" AND service.version=\"1.1\""
|
||||
'''
|
||||
headers=auth_header,
|
||||
)
|
||||
list_knocks_json = list_knocks_response.json()
|
||||
|
||||
string room = 2;
|
||||
|
||||
string display_name = 2;
|
||||
}
|
||||
for knock in list_knocks_json["knocks"]:
|
||||
# Spin off a process to handle the knock
|
||||
p = Process(target=instance.serve, args=(knock))
|
||||
p.start()
|
||||
time.sleep(1)
|
||||
|
||||
message Service {
|
||||
string protocol = 1;
|
||||
string version = 2;
|
||||
```
|
||||
|
||||
// Used to define custom fields per-protocol/version.
|
||||
// We use unverified extensions because this system is meant
|
||||
// to be distributed, with no central owner, hence, no singular
|
||||
// authority to hand out field numbers. Instead, implementations
|
||||
// should use the protocol/version to scope what values are expected.
|
||||
extensions 100 to max [verification = UNVERIFIED];
|
||||
}
|
||||
instance.py
|
||||
```
|
||||
import asyncio
|
||||
from multiprocessing import Process
|
||||
from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription
|
||||
|
||||
message Knock {
|
||||
|
||||
repeated IceCandidate ice_candidates = 1;
|
||||
}
|
||||
async def serve(url, auth_header, knock):
|
||||
peer_connection = RTCPeerConnection()
|
||||
await peer_connection.set_remote_description(knock.client_session_description)
|
||||
await pc.setLocalDescription(await peer_connection.createAnswer())
|
||||
for ice_candidate in knock['ice_candidates']:
|
||||
await peer_connection.addIceCandidate(ice_candidate)
|
||||
# Gather local ICE candidates
|
||||
|
||||
message IceCandidate {
|
||||
// Copied from https://pkg.go.dev/github.com/pion/webrtc/v4#ICECandidateInit
|
||||
string candidate = 1;
|
||||
optional string sdp_mid = 2;
|
||||
optional int32 sdp_line_index = 3;
|
||||
optional string username_fragment = 4;
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
72
demo_server/.dockerignore
Normal file
72
demo_server/.dockerignore
Normal file
@@ -0,0 +1,72 @@
|
||||
.travis.yaml
|
||||
.openapi-generator-ignore
|
||||
README.md
|
||||
tox.ini
|
||||
git_push.sh
|
||||
test-requirements.txt
|
||||
setup.py
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
venv/
|
||||
.python-version
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
#Ipython Notebook
|
||||
.ipynb_checkpoints
|
||||
66
demo_server/.gitignore
vendored
Normal file
66
demo_server/.gitignore
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
venv/
|
||||
.venv/
|
||||
.python-version
|
||||
.pytest_cache
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
#Ipython Notebook
|
||||
.ipynb_checkpoints
|
||||
23
demo_server/.openapi-generator-ignore
Normal file
23
demo_server/.openapi-generator-ignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
32
demo_server/.openapi-generator/FILES
Normal file
32
demo_server/.openapi-generator/FILES
Normal file
@@ -0,0 +1,32 @@
|
||||
.dockerignore
|
||||
.gitignore
|
||||
.travis.yml
|
||||
Dockerfile
|
||||
README.md
|
||||
git_push.sh
|
||||
openapi_server/__init__.py
|
||||
openapi_server/__main__.py
|
||||
openapi_server/controllers/__init__.py
|
||||
openapi_server/controllers/peer_net_service_controller.py
|
||||
openapi_server/controllers/security_controller.py
|
||||
openapi_server/encoder.py
|
||||
openapi_server/models/__init__.py
|
||||
openapi_server/models/base_model.py
|
||||
openapi_server/models/claim_ice_candidates_response.py
|
||||
openapi_server/models/google_protobuf_any.py
|
||||
openapi_server/models/ice_candidate.py
|
||||
openapi_server/models/ice_session_description.py
|
||||
openapi_server/models/knock.py
|
||||
openapi_server/models/list_knocks_response.py
|
||||
openapi_server/models/room.py
|
||||
openapi_server/models/server.py
|
||||
openapi_server/models/service.py
|
||||
openapi_server/models/status.py
|
||||
openapi_server/openapi/openapi.yaml
|
||||
openapi_server/test/__init__.py
|
||||
openapi_server/typing_utils.py
|
||||
openapi_server/util.py
|
||||
requirements.txt
|
||||
setup.py
|
||||
test-requirements.txt
|
||||
tox.ini
|
||||
1
demo_server/.openapi-generator/VERSION
Normal file
1
demo_server/.openapi-generator/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
7.4.0
|
||||
14
demo_server/.travis.yml
Normal file
14
demo_server/.travis.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
# ref: https://docs.travis-ci.com/user/languages/python
|
||||
language: python
|
||||
python:
|
||||
- "3.2"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
# command to install dependencies
|
||||
install: "pip install -r requirements.txt"
|
||||
# command to run tests
|
||||
script: nosetests
|
||||
16
demo_server/Dockerfile
Normal file
16
demo_server/Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
FROM python:3-alpine
|
||||
|
||||
RUN mkdir -p /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY requirements.txt /usr/src/app/
|
||||
|
||||
RUN pip3 install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . /usr/src/app
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["python3"]
|
||||
|
||||
CMD ["-m", "openapi_server"]
|
||||
49
demo_server/README.md
Normal file
49
demo_server/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# OpenAPI generated server
|
||||
|
||||
## Overview
|
||||
This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the
|
||||
[OpenAPI-Spec](https://openapis.org) from a remote server, you can easily generate a server stub. This
|
||||
is an example of building a OpenAPI-enabled Flask server.
|
||||
|
||||
This example uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask.
|
||||
|
||||
## Requirements
|
||||
Python 3.5.2+
|
||||
|
||||
## Usage
|
||||
To run the server, please execute the following from the root directory:
|
||||
|
||||
```
|
||||
pip3 install -r requirements.txt
|
||||
python3 -m openapi_server
|
||||
```
|
||||
|
||||
and open your browser to here:
|
||||
|
||||
```
|
||||
http://localhost:8080/ui/
|
||||
```
|
||||
|
||||
Your OpenAPI definition lives here:
|
||||
|
||||
```
|
||||
http://localhost:8080/openapi.json
|
||||
```
|
||||
|
||||
To launch the integration tests, use tox:
|
||||
```
|
||||
sudo pip install tox
|
||||
tox
|
||||
```
|
||||
|
||||
## Running with Docker
|
||||
|
||||
To run the server on a Docker container, please execute the following from the root directory:
|
||||
|
||||
```bash
|
||||
# building the image
|
||||
docker build -t openapi_server .
|
||||
|
||||
# starting up a container
|
||||
docker run -p 8080:8080 openapi_server
|
||||
```
|
||||
38
demo_server/demo_client/.github/workflows/python.yml
vendored
Normal file
38
demo_server/demo_client/.github/workflows/python.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# NOTE: This file is auto generated by OpenAPI Generator.
|
||||
# URL: https://openapi-generator.tech
|
||||
#
|
||||
# ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
||||
|
||||
name: openapi_client Python package
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install flake8 pytest
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pytest
|
||||
66
demo_server/demo_client/.gitignore
vendored
Normal file
66
demo_server/demo_client/.gitignore
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
venv/
|
||||
.venv/
|
||||
.python-version
|
||||
.pytest_cache
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
#Ipython Notebook
|
||||
.ipynb_checkpoints
|
||||
31
demo_server/demo_client/.gitlab-ci.yml
Normal file
31
demo_server/demo_client/.gitlab-ci.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
# NOTE: This file is auto generated by OpenAPI Generator.
|
||||
# URL: https://openapi-generator.tech
|
||||
#
|
||||
# ref: https://docs.gitlab.com/ee/ci/README.html
|
||||
# ref: https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
||||
.pytest:
|
||||
stage: test
|
||||
script:
|
||||
- pip install -r requirements.txt
|
||||
- pip install -r test-requirements.txt
|
||||
- pytest --cov=openapi_client
|
||||
|
||||
pytest-3.7:
|
||||
extends: .pytest
|
||||
image: python:3.7-alpine
|
||||
pytest-3.8:
|
||||
extends: .pytest
|
||||
image: python:3.8-alpine
|
||||
pytest-3.9:
|
||||
extends: .pytest
|
||||
image: python:3.9-alpine
|
||||
pytest-3.10:
|
||||
extends: .pytest
|
||||
image: python:3.10-alpine
|
||||
pytest-3.11:
|
||||
extends: .pytest
|
||||
image: python:3.11-alpine
|
||||
23
demo_server/demo_client/.openapi-generator-ignore
Normal file
23
demo_server/demo_client/.openapi-generator-ignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
44
demo_server/demo_client/.openapi-generator/FILES
Normal file
44
demo_server/demo_client/.openapi-generator/FILES
Normal file
@@ -0,0 +1,44 @@
|
||||
.github/workflows/python.yml
|
||||
.gitignore
|
||||
.gitlab-ci.yml
|
||||
.travis.yml
|
||||
README.md
|
||||
docs/ClaimIceCandidatesResponse.md
|
||||
docs/GoogleProtobufAny.md
|
||||
docs/IceCandidate.md
|
||||
docs/IceSessionDescription.md
|
||||
docs/Knock.md
|
||||
docs/ListKnocksResponse.md
|
||||
docs/PeerNetServiceApi.md
|
||||
docs/Room.md
|
||||
docs/Server.md
|
||||
docs/Service.md
|
||||
docs/Status.md
|
||||
git_push.sh
|
||||
openapi_client/__init__.py
|
||||
openapi_client/api/__init__.py
|
||||
openapi_client/api/peer_net_service_api.py
|
||||
openapi_client/api_client.py
|
||||
openapi_client/api_response.py
|
||||
openapi_client/configuration.py
|
||||
openapi_client/exceptions.py
|
||||
openapi_client/models/__init__.py
|
||||
openapi_client/models/claim_ice_candidates_response.py
|
||||
openapi_client/models/google_protobuf_any.py
|
||||
openapi_client/models/ice_candidate.py
|
||||
openapi_client/models/ice_session_description.py
|
||||
openapi_client/models/knock.py
|
||||
openapi_client/models/list_knocks_response.py
|
||||
openapi_client/models/room.py
|
||||
openapi_client/models/server.py
|
||||
openapi_client/models/service.py
|
||||
openapi_client/models/status.py
|
||||
openapi_client/py.typed
|
||||
openapi_client/rest.py
|
||||
pyproject.toml
|
||||
requirements.txt
|
||||
setup.cfg
|
||||
setup.py
|
||||
test-requirements.txt
|
||||
test/__init__.py
|
||||
tox.ini
|
||||
1
demo_server/demo_client/.openapi-generator/VERSION
Normal file
1
demo_server/demo_client/.openapi-generator/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
7.4.0
|
||||
17
demo_server/demo_client/.travis.yml
Normal file
17
demo_server/demo_client/.travis.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# ref: https://docs.travis-ci.com/user/languages/python
|
||||
language: python
|
||||
python:
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
# uncomment the following if needed
|
||||
#- "3.11-dev" # 3.11 development branch
|
||||
#- "nightly" # nightly build
|
||||
# command to install dependencies
|
||||
install:
|
||||
- "pip install -r requirements.txt"
|
||||
- "pip install -r test-requirements.txt"
|
||||
# command to run tests
|
||||
script: pytest --cov=openapi_client
|
||||
124
demo_server/demo_client/README.md
Normal file
124
demo_server/demo_client/README.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# openapi-client
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||
|
||||
- API version: 0.0.1
|
||||
- Package version: 1.0.0
|
||||
- Generator version: 7.4.0
|
||||
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
|
||||
|
||||
## Requirements.
|
||||
|
||||
Python 3.7+
|
||||
|
||||
## Installation & Usage
|
||||
### pip install
|
||||
|
||||
If the python package is hosted on a repository, you can install directly using:
|
||||
|
||||
```sh
|
||||
pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git
|
||||
```
|
||||
(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`)
|
||||
|
||||
Then import the package:
|
||||
```python
|
||||
import openapi_client
|
||||
```
|
||||
|
||||
### Setuptools
|
||||
|
||||
Install via [Setuptools](http://pypi.python.org/pypi/setuptools).
|
||||
|
||||
```sh
|
||||
python setup.py install --user
|
||||
```
|
||||
(or `sudo python setup.py install` to install the package for all users)
|
||||
|
||||
Then import the package:
|
||||
```python
|
||||
import openapi_client
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
Execute `pytest` to run the tests.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Please follow the [installation procedure](#installation--usage) and then run the following:
|
||||
|
||||
```python
|
||||
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
session = 'session_example' # str | The session id.
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_claim_ice_candidates(session)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_claim_ice_candidates:\n")
|
||||
pprint(api_response)
|
||||
except ApiException as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_claim_ice_candidates: %s\n" % e)
|
||||
|
||||
```
|
||||
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*PeerNetServiceApi* | [**peer_net_service_claim_ice_candidates**](docs/PeerNetServiceApi.md#peer_net_service_claim_ice_candidates) | **GET** /v1/sessions/{session}/claim/candidates |
|
||||
*PeerNetServiceApi* | [**peer_net_service_create_ice_candidate**](docs/PeerNetServiceApi.md#peer_net_service_create_ice_candidate) | **POST** /v1/sessions/{session}/candidates |
|
||||
*PeerNetServiceApi* | [**peer_net_service_create_knock**](docs/PeerNetServiceApi.md#peer_net_service_create_knock) | **POST** /v1/servers/{server}/services/{service}/knocks |
|
||||
*PeerNetServiceApi* | [**peer_net_service_create_server**](docs/PeerNetServiceApi.md#peer_net_service_create_server) | **POST** /v1/servers |
|
||||
*PeerNetServiceApi* | [**peer_net_service_create_service**](docs/PeerNetServiceApi.md#peer_net_service_create_service) | **POST** /v1/servers/{server}/services |
|
||||
*PeerNetServiceApi* | [**peer_net_service_delete_server**](docs/PeerNetServiceApi.md#peer_net_service_delete_server) | **DELETE** /v1/servers/* |
|
||||
*PeerNetServiceApi* | [**peer_net_service_delete_service**](docs/PeerNetServiceApi.md#peer_net_service_delete_service) | **DELETE** /v1/servers/{server}/services/{service} |
|
||||
*PeerNetServiceApi* | [**peer_net_service_get_knock**](docs/PeerNetServiceApi.md#peer_net_service_get_knock) | **GET** /v1/servers/{server}/services/{service}/knocks/{knock} |
|
||||
*PeerNetServiceApi* | [**peer_net_service_get_room**](docs/PeerNetServiceApi.md#peer_net_service_get_room) | **GET** /v1/rooms/{room} |
|
||||
*PeerNetServiceApi* | [**peer_net_service_list_knocks**](docs/PeerNetServiceApi.md#peer_net_service_list_knocks) | **GET** /v1/servers/{server}/services/{service}/knocks |
|
||||
*PeerNetServiceApi* | [**peer_net_service_update_knock**](docs/PeerNetServiceApi.md#peer_net_service_update_knock) | **PATCH** /v1/servers/{server}/services/{service}/knocks/{knock} |
|
||||
|
||||
|
||||
## Documentation For Models
|
||||
|
||||
- [ClaimIceCandidatesResponse](docs/ClaimIceCandidatesResponse.md)
|
||||
- [GoogleProtobufAny](docs/GoogleProtobufAny.md)
|
||||
- [IceCandidate](docs/IceCandidate.md)
|
||||
- [IceSessionDescription](docs/IceSessionDescription.md)
|
||||
- [Knock](docs/Knock.md)
|
||||
- [ListKnocksResponse](docs/ListKnocksResponse.md)
|
||||
- [Room](docs/Room.md)
|
||||
- [Server](docs/Server.md)
|
||||
- [Service](docs/Service.md)
|
||||
- [Status](docs/Status.md)
|
||||
|
||||
|
||||
<a id="documentation-for-authorization"></a>
|
||||
## Documentation For Authorization
|
||||
|
||||
Endpoints do not require authorization.
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
|
||||
|
||||
112
demo_server/demo_client/demo.py
Normal file
112
demo_server/demo_client/demo.py
Normal file
@@ -0,0 +1,112 @@
|
||||
import time
|
||||
import asyncio
|
||||
from multiprocessing import Process
|
||||
from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
from aiortc import RTCPeerConnection, RTCSessionDescription
|
||||
from aiortc.sdp import candidate_from_sdp, candidate_to_sdp
|
||||
import uuid
|
||||
import openapi_client
|
||||
|
||||
# Defining the host is optional and defaults to http://127.0.0.1:8080
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://127.0.0.1:8080"
|
||||
)
|
||||
|
||||
server_name="myserver"
|
||||
service_name="http1"
|
||||
|
||||
|
||||
|
||||
def serve(peernet, knock, server_name):
|
||||
|
||||
async def server_internal():
|
||||
pc = RTCPeerConnection()
|
||||
|
||||
# Define our handlers
|
||||
done = False
|
||||
session = "%s" % uuid.uuid4()
|
||||
|
||||
@pc.on("datachannel")
|
||||
def on_datachannel(channel):
|
||||
@channel.on("message")
|
||||
def on_message(message):
|
||||
# Process the message, and send a response
|
||||
channel.send("pong" + message[4:])
|
||||
|
||||
@pc.on("connectionstatechange")
|
||||
async def on_connectionstatechange():
|
||||
if pc.connectionState == "failed":
|
||||
done = True
|
||||
await pc.close()
|
||||
|
||||
@pc.on("icecandidate")
|
||||
async def on_icecandidate(candidate):
|
||||
peernet.peer_net_service_create_ice_candidatge(session=knock.offer.name, ice_candidate={
|
||||
"candidate": candidate_to_sdp(obj),
|
||||
"sdpMid": obj.sdpMid,
|
||||
"sdpLineIndex": obj.sdpMLineIndex,
|
||||
})
|
||||
|
||||
|
||||
# Add the remote offer
|
||||
offer = RTCSessionDescription(sdp=knock.offer.sdp, type="offer")
|
||||
await pc.setRemoteDescription(offer)
|
||||
# Create an answer
|
||||
answer = await pc.createAnswer()
|
||||
await pc.setLocalDescription(answer)
|
||||
# Send the answer
|
||||
session_id = "%s" % uuid.uuid4()
|
||||
knock.answer = {
|
||||
"name": session_id,
|
||||
"sdp": answer.sdp,
|
||||
"sdpType": answer.type,
|
||||
}
|
||||
peernet.peer_net_service_update_knock(server_name, service_name, knock.name, knock2=knock)
|
||||
|
||||
while not done:
|
||||
resp = peernet.peer_net_service_claim_ice_candidates(session_id)
|
||||
if resp.ice_candidates != None:
|
||||
time.sleep(1)
|
||||
continue
|
||||
for candidate in resp.ice_candidates:
|
||||
ice_candidate = candidate_from_sdp(candidate.candidate)
|
||||
ice_candidate.sdpMid = candidate.sdpMid
|
||||
ice_candidate.sdpMLineIndex = candidate.sdpLineIndex
|
||||
await pc.addIceCandidate(candidate)
|
||||
coro = server_internal()
|
||||
|
||||
# run event loop
|
||||
loop = asyncio.get_event_loop()
|
||||
try:
|
||||
loop.run_until_complete(coro)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
peernet = openapi_client.PeerNetServiceApi(api_client)
|
||||
|
||||
resp = peernet.peer_net_service_create_server(server={
|
||||
"name": server_name,
|
||||
"rooms": ["room1"],
|
||||
"services": [
|
||||
{
|
||||
"name": service_name,
|
||||
"protocol": "http",
|
||||
"version": "1.0",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
while True:
|
||||
print("Checking for knocks")
|
||||
resp = peernet.peer_net_service_list_knocks(server=server_name, service=service_name)
|
||||
for knock in resp.knocks:
|
||||
print("Processing %s", knock)
|
||||
p = Process(target=serve, args=(peernet, knock, server_name))
|
||||
p.start()
|
||||
time.sleep(5)
|
||||
103
demo_server/demo_client/demo_client.py
Normal file
103
demo_server/demo_client/demo_client.py
Normal file
@@ -0,0 +1,103 @@
|
||||
import time
|
||||
import asyncio
|
||||
from multiprocessing import Process
|
||||
from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
from aiortc import RTCPeerConnection, RTCSessionDescription
|
||||
from aiortc.sdp import candidate_from_sdp, candidate_to_sdp
|
||||
import uuid
|
||||
import openapi_client
|
||||
|
||||
async def run():
|
||||
# Defining the host is optional and defaults to http://127.0.0.1:8080
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://127.0.0.1:8080"
|
||||
)
|
||||
|
||||
server_name="myserver"
|
||||
service_name="http1"
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
peernet = openapi_client.PeerNetServiceApi(api_client)
|
||||
|
||||
pc = RTCPeerConnection()
|
||||
channel = pc.createDataChannel("http1")
|
||||
|
||||
# Define our handlers
|
||||
done = False
|
||||
session = "%s" % uuid.uuid4()
|
||||
|
||||
@channel.on("open")
|
||||
def on_open():
|
||||
print("Connection established!")
|
||||
|
||||
@pc.on("datachannel")
|
||||
def on_datachannel(channel):
|
||||
@channel.on("message")
|
||||
def on_message(message):
|
||||
# Process the message, and send a response
|
||||
channel.send("<html><body>Hello world</body></html>")
|
||||
|
||||
@pc.on("connectionstatechange")
|
||||
async def on_connectionstatechange():
|
||||
if pc.connectionState == "failed":
|
||||
done = True
|
||||
await pc.close()
|
||||
|
||||
@pc.on("icecandidate")
|
||||
async def on_icecandidate(candidate):
|
||||
peernet.peer_net_service_create_ice_candidatge(session=knock.offer.name, ice_candidate={
|
||||
"candidate": candidate_to_sdp(obj),
|
||||
"sdpMid": obj.sdpMid,
|
||||
"sdpLineIndex": obj.sdpMLineIndex,
|
||||
})
|
||||
|
||||
offer = await pc.createOffer()
|
||||
await pc.setLocalDescription(offer)
|
||||
|
||||
knock_name = "%s" % uuid.uuid4()
|
||||
peernet.peer_net_service_create_knock(server=server_name, service=service_name, knock={
|
||||
"name": knock_name,
|
||||
"offer": {
|
||||
"name": session,
|
||||
"sdp": offer.sdp,
|
||||
},
|
||||
})
|
||||
|
||||
# Poll the server waiting for answer
|
||||
answer = None
|
||||
while True:
|
||||
print("Checking for knocks")
|
||||
resp = peernet.peer_net_service_get_knock(server_name, service_name, knock_name)
|
||||
print("%s", resp)
|
||||
if resp.answer != None:
|
||||
answer = resp.answer
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
await pc.setRemoteDescription(RTCSessionDescription(sdp=answer.sdp, type="answer"))
|
||||
# Start connecting ice candidates!
|
||||
|
||||
while not done:
|
||||
resp = peernet.peer_net_service_claim_ice_candidates(session)
|
||||
if resp.ice_candidates != None:
|
||||
time.sleep(1)
|
||||
continue
|
||||
for candidate in resp.ice_candidates:
|
||||
ice_candidate = candidate_from_sdp(candidate.candidate)
|
||||
ice_candidate.sdpMid = candidate.sdpMid
|
||||
ice_candidate.sdpMLineIndex = candidate.sdpLineIndex
|
||||
await pc.addIceCandidate(candidate)
|
||||
|
||||
coro = run()
|
||||
|
||||
# run event loop
|
||||
loop = asyncio.get_event_loop()
|
||||
try:
|
||||
loop.run_until_complete(coro)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
29
demo_server/demo_client/docs/ClaimIceCandidatesResponse.md
Normal file
29
demo_server/demo_client/docs/ClaimIceCandidatesResponse.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# ClaimIceCandidatesResponse
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**ice_candidates** | [**List[IceCandidate]**](IceCandidate.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ClaimIceCandidatesResponse from a JSON string
|
||||
claim_ice_candidates_response_instance = ClaimIceCandidatesResponse.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ClaimIceCandidatesResponse.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
claim_ice_candidates_response_dict = claim_ice_candidates_response_instance.to_dict()
|
||||
# create an instance of ClaimIceCandidatesResponse from a dict
|
||||
claim_ice_candidates_response_form_dict = claim_ice_candidates_response.from_dict(claim_ice_candidates_response_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
30
demo_server/demo_client/docs/GoogleProtobufAny.md
Normal file
30
demo_server/demo_client/docs/GoogleProtobufAny.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# GoogleProtobufAny
|
||||
|
||||
Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**type** | **str** | The type of the serialized message. | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.google_protobuf_any import GoogleProtobufAny
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of GoogleProtobufAny from a JSON string
|
||||
google_protobuf_any_instance = GoogleProtobufAny.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(GoogleProtobufAny.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
google_protobuf_any_dict = google_protobuf_any_instance.to_dict()
|
||||
# create an instance of GoogleProtobufAny from a dict
|
||||
google_protobuf_any_form_dict = google_protobuf_any.from_dict(google_protobuf_any_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
33
demo_server/demo_client/docs/IceCandidate.md
Normal file
33
demo_server/demo_client/docs/IceCandidate.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# IceCandidate
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**candidate** | **str** | | [optional]
|
||||
**sdp_mid** | **str** | | [optional]
|
||||
**sdp_line_index** | **int** | | [optional]
|
||||
**username_fragment** | **str** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of IceCandidate from a JSON string
|
||||
ice_candidate_instance = IceCandidate.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(IceCandidate.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
ice_candidate_dict = ice_candidate_instance.to_dict()
|
||||
# create an instance of IceCandidate from a dict
|
||||
ice_candidate_form_dict = ice_candidate.from_dict(ice_candidate_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
31
demo_server/demo_client/docs/IceSessionDescription.md
Normal file
31
demo_server/demo_client/docs/IceSessionDescription.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# IceSessionDescription
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | A unique identifier which can be used to send ICE candidates Maps to the session name | [optional]
|
||||
**sdp_type** | **str** | Used to construct the remote description in WebRTC | [optional]
|
||||
**sdp** | **str** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.ice_session_description import IceSessionDescription
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of IceSessionDescription from a JSON string
|
||||
ice_session_description_instance = IceSessionDescription.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(IceSessionDescription.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
ice_session_description_dict = ice_session_description_instance.to_dict()
|
||||
# create an instance of IceSessionDescription from a dict
|
||||
ice_session_description_form_dict = ice_session_description.from_dict(ice_session_description_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
31
demo_server/demo_client/docs/Knock.md
Normal file
31
demo_server/demo_client/docs/Knock.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Knock
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**offer** | [**IceSessionDescription**](IceSessionDescription.md) | The service being connected too | [optional]
|
||||
**answer** | [**IceSessionDescription**](IceSessionDescription.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.knock import Knock
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Knock from a JSON string
|
||||
knock_instance = Knock.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Knock.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
knock_dict = knock_instance.to_dict()
|
||||
# create an instance of Knock from a dict
|
||||
knock_form_dict = knock.from_dict(knock_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
29
demo_server/demo_client/docs/ListKnocksResponse.md
Normal file
29
demo_server/demo_client/docs/ListKnocksResponse.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# ListKnocksResponse
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**knocks** | [**List[Knock]**](Knock.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.list_knocks_response import ListKnocksResponse
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ListKnocksResponse from a JSON string
|
||||
list_knocks_response_instance = ListKnocksResponse.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(ListKnocksResponse.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
list_knocks_response_dict = list_knocks_response_instance.to_dict()
|
||||
# create an instance of ListKnocksResponse from a dict
|
||||
list_knocks_response_form_dict = list_knocks_response.from_dict(list_knocks_response_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
765
demo_server/demo_client/docs/PeerNetServiceApi.md
Normal file
765
demo_server/demo_client/docs/PeerNetServiceApi.md
Normal file
@@ -0,0 +1,765 @@
|
||||
# openapi_client.PeerNetServiceApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**peer_net_service_claim_ice_candidates**](PeerNetServiceApi.md#peer_net_service_claim_ice_candidates) | **GET** /v1/sessions/{session}/claim/candidates |
|
||||
[**peer_net_service_create_ice_candidate**](PeerNetServiceApi.md#peer_net_service_create_ice_candidate) | **POST** /v1/sessions/{session}/candidates |
|
||||
[**peer_net_service_create_knock**](PeerNetServiceApi.md#peer_net_service_create_knock) | **POST** /v1/servers/{server}/services/{service}/knocks |
|
||||
[**peer_net_service_create_server**](PeerNetServiceApi.md#peer_net_service_create_server) | **POST** /v1/servers |
|
||||
[**peer_net_service_create_service**](PeerNetServiceApi.md#peer_net_service_create_service) | **POST** /v1/servers/{server}/services |
|
||||
[**peer_net_service_delete_server**](PeerNetServiceApi.md#peer_net_service_delete_server) | **DELETE** /v1/servers/* |
|
||||
[**peer_net_service_delete_service**](PeerNetServiceApi.md#peer_net_service_delete_service) | **DELETE** /v1/servers/{server}/services/{service} |
|
||||
[**peer_net_service_get_knock**](PeerNetServiceApi.md#peer_net_service_get_knock) | **GET** /v1/servers/{server}/services/{service}/knocks/{knock} |
|
||||
[**peer_net_service_get_room**](PeerNetServiceApi.md#peer_net_service_get_room) | **GET** /v1/rooms/{room} |
|
||||
[**peer_net_service_list_knocks**](PeerNetServiceApi.md#peer_net_service_list_knocks) | **GET** /v1/servers/{server}/services/{service}/knocks |
|
||||
[**peer_net_service_update_knock**](PeerNetServiceApi.md#peer_net_service_update_knock) | **PATCH** /v1/servers/{server}/services/{service}/knocks/{knock} |
|
||||
|
||||
|
||||
# **peer_net_service_claim_ice_candidates**
|
||||
> ClaimIceCandidatesResponse peer_net_service_claim_ice_candidates(session)
|
||||
|
||||
|
||||
|
||||
Acts as both List and Delete atomically.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
session = 'session_example' # str | The session id.
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_claim_ice_candidates(session)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_claim_ice_candidates:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_claim_ice_candidates: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**session** | **str**| The session id. |
|
||||
|
||||
### Return type
|
||||
|
||||
[**ClaimIceCandidatesResponse**](ClaimIceCandidatesResponse.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_create_ice_candidate**
|
||||
> IceCandidate peer_net_service_create_ice_candidate(session, ice_candidate)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
session = 'session_example' # str | The session id.
|
||||
ice_candidate = openapi_client.IceCandidate() # IceCandidate |
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_create_ice_candidate(session, ice_candidate)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_create_ice_candidate:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_create_ice_candidate: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**session** | **str**| The session id. |
|
||||
**ice_candidate** | [**IceCandidate**](IceCandidate.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**IceCandidate**](IceCandidate.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_create_knock**
|
||||
> Knock peer_net_service_create_knock(server, service, knock)
|
||||
|
||||
|
||||
|
||||
Creates a knock that will be answered by the peer; the signaler may delete the knock, regardless of the state, when it ages.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.knock import Knock
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = 'service_example' # str | The service id.
|
||||
knock = openapi_client.Knock() # Knock |
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_create_knock(server, service, knock)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_create_knock:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_create_knock: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | **str**| The service id. |
|
||||
**knock** | [**Knock**](Knock.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Knock**](Knock.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_create_server**
|
||||
> Server peer_net_service_create_server(server)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.server import Server
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = openapi_client.Server() # Server |
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_create_server(server)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_create_server:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_create_server: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | [**Server**](Server.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Server**](Server.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_create_service**
|
||||
> Service peer_net_service_create_service(server, service)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = openapi_client.Service() # Service |
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_create_service(server, service)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_create_service:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_create_service: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | [**Service**](Service.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_delete_server**
|
||||
> peer_net_service_delete_server(name=name)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
name = 'name_example' # str | (optional)
|
||||
|
||||
try:
|
||||
api_instance.peer_net_service_delete_server(name=name)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_delete_server: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**name** | **str**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
void (empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_delete_service**
|
||||
> peer_net_service_delete_service(server, service)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = 'service_example' # str | The service id.
|
||||
|
||||
try:
|
||||
api_instance.peer_net_service_delete_service(server, service)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_delete_service: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | **str**| The service id. |
|
||||
|
||||
### Return type
|
||||
|
||||
void (empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_get_knock**
|
||||
> Knock peer_net_service_get_knock(server, service, knock)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.knock import Knock
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = 'service_example' # str | The service id.
|
||||
knock = 'knock_example' # str | The knock id.
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_get_knock(server, service, knock)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_get_knock:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_get_knock: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | **str**| The service id. |
|
||||
**knock** | **str**| The knock id. |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Knock**](Knock.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_get_room**
|
||||
> Room peer_net_service_get_room(room)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.room import Room
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
room = 'room_example' # str | The room id.
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_get_room(room)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_get_room:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_get_room: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**room** | **str**| The room id. |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Room**](Room.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_list_knocks**
|
||||
> ListKnocksResponse peer_net_service_list_knocks(server, service)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.list_knocks_response import ListKnocksResponse
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = 'service_example' # str | The service id.
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_list_knocks(server, service)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_list_knocks:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_list_knocks: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | **str**| The service id. |
|
||||
|
||||
### Return type
|
||||
|
||||
[**ListKnocksResponse**](ListKnocksResponse.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **peer_net_service_update_knock**
|
||||
> Knock peer_net_service_update_knock(server, service, knock, knock2)
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
```python
|
||||
import openapi_client
|
||||
from openapi_client.models.knock import Knock
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.PeerNetServiceApi(api_client)
|
||||
server = 'server_example' # str | The server id.
|
||||
service = 'service_example' # str | The service id.
|
||||
knock = 'knock_example' # str | The knock id.
|
||||
knock2 = openapi_client.Knock() # Knock |
|
||||
|
||||
try:
|
||||
api_response = api_instance.peer_net_service_update_knock(server, service, knock, knock2)
|
||||
print("The response of PeerNetServiceApi->peer_net_service_update_knock:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling PeerNetServiceApi->peer_net_service_update_knock: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**server** | **str**| The server id. |
|
||||
**service** | **str**| The service id. |
|
||||
**knock** | **str**| The knock id. |
|
||||
**knock2** | [**Knock**](Knock.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Knock**](Knock.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | OK | - |
|
||||
**0** | Default error response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
31
demo_server/demo_client/docs/Room.md
Normal file
31
demo_server/demo_client/docs/Room.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Room
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**display_name** | **str** | | [optional]
|
||||
**servers** | [**List[Server]**](Server.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.room import Room
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Room from a JSON string
|
||||
room_instance = Room.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Room.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
room_dict = room_instance.to_dict()
|
||||
# create an instance of Room from a dict
|
||||
room_form_dict = room.from_dict(room_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
33
demo_server/demo_client/docs/Server.md
Normal file
33
demo_server/demo_client/docs/Server.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Server
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**rooms** | **List[str]** | Tracks which rooms the server should be listed in; this will not be set when a room is listed to preserve privacy of servers. | [optional]
|
||||
**auth_token** | **str** | Used to authenticate requests which access knocks for this server or attempt to update, delete or create services. In future calls, add a header with the format: Authorization: Bearer <auth_token> | [optional]
|
||||
**display_name** | **str** | | [optional]
|
||||
**services** | [**List[Service]**](Service.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.server import Server
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Server from a JSON string
|
||||
server_instance = Server.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Server.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
server_dict = server_instance.to_dict()
|
||||
# create an instance of Server from a dict
|
||||
server_form_dict = server.from_dict(server_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
31
demo_server/demo_client/docs/Service.md
Normal file
31
demo_server/demo_client/docs/Service.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Service
|
||||
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | | [optional]
|
||||
**protocol** | **str** | | [optional]
|
||||
**version** | **str** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.service import Service
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Service from a JSON string
|
||||
service_instance = Service.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Service.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
service_dict = service_instance.to_dict()
|
||||
# create an instance of Service from a dict
|
||||
service_form_dict = service.from_dict(service_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
32
demo_server/demo_client/docs/Status.md
Normal file
32
demo_server/demo_client/docs/Status.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Status
|
||||
|
||||
The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).
|
||||
|
||||
## Properties
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**code** | **int** | The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. | [optional]
|
||||
**message** | **str** | A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. | [optional]
|
||||
**details** | [**List[GoogleProtobufAny]**](GoogleProtobufAny.md) | A list of messages that carry the error details. There is a common set of message types for APIs to use. | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.status import Status
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Status from a JSON string
|
||||
status_instance = Status.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print(Status.to_json())
|
||||
|
||||
# convert the object into a dict
|
||||
status_dict = status_instance.to_dict()
|
||||
# create an instance of Status from a dict
|
||||
status_form_dict = status.from_dict(status_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
57
demo_server/demo_client/git_push.sh
Normal file
57
demo_server/demo_client/git_push.sh
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
git_host=$4
|
||||
|
||||
if [ "$git_host" = "" ]; then
|
||||
git_host="github.com"
|
||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
||||
fi
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="GIT_USER_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="GIT_REPO_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="Minor update"
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=$(git remote)
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
43
demo_server/demo_client/openapi_client/__init__.py
Normal file
43
demo_server/demo_client/openapi_client/__init__.py
Normal file
@@ -0,0 +1,43 @@
|
||||
# coding: utf-8
|
||||
|
||||
# flake8: noqa
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
__version__ = "1.0.0"
|
||||
|
||||
# import apis into sdk package
|
||||
from openapi_client.api.peer_net_service_api import PeerNetServiceApi
|
||||
|
||||
# import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.configuration import Configuration
|
||||
from openapi_client.exceptions import OpenApiException
|
||||
from openapi_client.exceptions import ApiTypeError
|
||||
from openapi_client.exceptions import ApiValueError
|
||||
from openapi_client.exceptions import ApiKeyError
|
||||
from openapi_client.exceptions import ApiAttributeError
|
||||
from openapi_client.exceptions import ApiException
|
||||
|
||||
# import models into sdk package
|
||||
from openapi_client.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
from openapi_client.models.google_protobuf_any import GoogleProtobufAny
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
from openapi_client.models.ice_session_description import IceSessionDescription
|
||||
from openapi_client.models.knock import Knock
|
||||
from openapi_client.models.list_knocks_response import ListKnocksResponse
|
||||
from openapi_client.models.room import Room
|
||||
from openapi_client.models.server import Server
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.status import Status
|
||||
5
demo_server/demo_client/openapi_client/api/__init__.py
Normal file
5
demo_server/demo_client/openapi_client/api/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# flake8: noqa
|
||||
|
||||
# import apis into api package
|
||||
from openapi_client.api.peer_net_service_api import PeerNetServiceApi
|
||||
|
||||
3077
demo_server/demo_client/openapi_client/api/peer_net_service_api.py
Normal file
3077
demo_server/demo_client/openapi_client/api/peer_net_service_api.py
Normal file
File diff suppressed because it is too large
Load Diff
758
demo_server/demo_client/openapi_client/api_client.py
Normal file
758
demo_server/demo_client/openapi_client/api_client.py
Normal file
@@ -0,0 +1,758 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import datetime
|
||||
from dateutil.parser import parse
|
||||
from enum import Enum
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
from urllib.parse import quote
|
||||
from typing import Tuple, Optional, List, Dict
|
||||
|
||||
from openapi_client.configuration import Configuration
|
||||
from openapi_client.api_response import ApiResponse, T as ApiResponseT
|
||||
import openapi_client.models
|
||||
from openapi_client import rest
|
||||
from openapi_client.exceptions import (
|
||||
ApiValueError,
|
||||
ApiException,
|
||||
BadRequestException,
|
||||
UnauthorizedException,
|
||||
ForbiddenException,
|
||||
NotFoundException,
|
||||
ServiceException
|
||||
)
|
||||
|
||||
RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]
|
||||
|
||||
class ApiClient:
|
||||
"""Generic API client for OpenAPI client library builds.
|
||||
|
||||
OpenAPI generic API client. This client handles the client-
|
||||
server communication, and is invariant across implementations. Specifics of
|
||||
the methods and models for each application are generated from the OpenAPI
|
||||
templates.
|
||||
|
||||
:param configuration: .Configuration object for this client
|
||||
:param header_name: a header to pass when making calls to the API.
|
||||
:param header_value: a header value to pass when making calls to
|
||||
the API.
|
||||
:param cookie: a cookie to include in the header when making calls
|
||||
to the API
|
||||
"""
|
||||
|
||||
PRIMITIVE_TYPES = (float, bool, bytes, str, int)
|
||||
NATIVE_TYPES_MAPPING = {
|
||||
'int': int,
|
||||
'long': int, # TODO remove as only py3 is supported?
|
||||
'float': float,
|
||||
'str': str,
|
||||
'bool': bool,
|
||||
'date': datetime.date,
|
||||
'datetime': datetime.datetime,
|
||||
'object': object,
|
||||
}
|
||||
_pool = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
configuration=None,
|
||||
header_name=None,
|
||||
header_value=None,
|
||||
cookie=None
|
||||
) -> None:
|
||||
# use default configuration if none is provided
|
||||
if configuration is None:
|
||||
configuration = Configuration.get_default()
|
||||
self.configuration = configuration
|
||||
|
||||
self.rest_client = rest.RESTClientObject(configuration)
|
||||
self.default_headers = {}
|
||||
if header_name is not None:
|
||||
self.default_headers[header_name] = header_value
|
||||
self.cookie = cookie
|
||||
# Set default User-Agent.
|
||||
self.user_agent = 'OpenAPI-Generator/1.0.0/python'
|
||||
self.client_side_validation = configuration.client_side_validation
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
pass
|
||||
|
||||
@property
|
||||
def user_agent(self):
|
||||
"""User agent for this API client"""
|
||||
return self.default_headers['User-Agent']
|
||||
|
||||
@user_agent.setter
|
||||
def user_agent(self, value):
|
||||
self.default_headers['User-Agent'] = value
|
||||
|
||||
def set_default_header(self, header_name, header_value):
|
||||
self.default_headers[header_name] = header_value
|
||||
|
||||
|
||||
_default = None
|
||||
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
"""Return new instance of ApiClient.
|
||||
|
||||
This method returns newly created, based on default constructor,
|
||||
object of ApiClient class or returns a copy of default
|
||||
ApiClient.
|
||||
|
||||
:return: The ApiClient object.
|
||||
"""
|
||||
if cls._default is None:
|
||||
cls._default = ApiClient()
|
||||
return cls._default
|
||||
|
||||
@classmethod
|
||||
def set_default(cls, default):
|
||||
"""Set default instance of ApiClient.
|
||||
|
||||
It stores default ApiClient.
|
||||
|
||||
:param default: object of ApiClient.
|
||||
"""
|
||||
cls._default = default
|
||||
|
||||
def param_serialize(
|
||||
self,
|
||||
method,
|
||||
resource_path,
|
||||
path_params=None,
|
||||
query_params=None,
|
||||
header_params=None,
|
||||
body=None,
|
||||
post_params=None,
|
||||
files=None, auth_settings=None,
|
||||
collection_formats=None,
|
||||
_host=None,
|
||||
_request_auth=None
|
||||
) -> RequestSerialized:
|
||||
|
||||
"""Builds the HTTP request params needed by the request.
|
||||
:param method: Method to call.
|
||||
:param resource_path: Path to method endpoint.
|
||||
:param path_params: Path parameters in the url.
|
||||
:param query_params: Query parameters in the url.
|
||||
:param header_params: Header parameters to be
|
||||
placed in the request header.
|
||||
:param body: Request body.
|
||||
:param post_params dict: Request post form parameters,
|
||||
for `application/x-www-form-urlencoded`, `multipart/form-data`.
|
||||
:param auth_settings list: Auth Settings names for the request.
|
||||
:param files dict: key -> filename, value -> filepath,
|
||||
for `multipart/form-data`.
|
||||
:param collection_formats: dict of collection formats for path, query,
|
||||
header, and post parameters.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:return: tuple of form (path, http_method, query_params, header_params,
|
||||
body, post_params, files)
|
||||
"""
|
||||
|
||||
config = self.configuration
|
||||
|
||||
# header parameters
|
||||
header_params = header_params or {}
|
||||
header_params.update(self.default_headers)
|
||||
if self.cookie:
|
||||
header_params['Cookie'] = self.cookie
|
||||
if header_params:
|
||||
header_params = self.sanitize_for_serialization(header_params)
|
||||
header_params = dict(
|
||||
self.parameters_to_tuples(header_params,collection_formats)
|
||||
)
|
||||
|
||||
# path parameters
|
||||
if path_params:
|
||||
path_params = self.sanitize_for_serialization(path_params)
|
||||
path_params = self.parameters_to_tuples(
|
||||
path_params,
|
||||
collection_formats
|
||||
)
|
||||
for k, v in path_params:
|
||||
# specified safe chars, encode everything
|
||||
resource_path = resource_path.replace(
|
||||
'{%s}' % k,
|
||||
quote(str(v), safe=config.safe_chars_for_path_param)
|
||||
)
|
||||
|
||||
# post parameters
|
||||
if post_params or files:
|
||||
post_params = post_params if post_params else []
|
||||
post_params = self.sanitize_for_serialization(post_params)
|
||||
post_params = self.parameters_to_tuples(
|
||||
post_params,
|
||||
collection_formats
|
||||
)
|
||||
post_params.extend(self.files_parameters(files))
|
||||
|
||||
# auth setting
|
||||
self.update_params_for_auth(
|
||||
header_params,
|
||||
query_params,
|
||||
auth_settings,
|
||||
resource_path,
|
||||
method,
|
||||
body,
|
||||
request_auth=_request_auth
|
||||
)
|
||||
|
||||
# body
|
||||
if body:
|
||||
body = self.sanitize_for_serialization(body)
|
||||
|
||||
# request url
|
||||
if _host is None:
|
||||
url = self.configuration.host + resource_path
|
||||
else:
|
||||
# use server/host defined in path or operation instead
|
||||
url = _host + resource_path
|
||||
|
||||
# query parameters
|
||||
if query_params:
|
||||
query_params = self.sanitize_for_serialization(query_params)
|
||||
url_query = self.parameters_to_url_query(
|
||||
query_params,
|
||||
collection_formats
|
||||
)
|
||||
url += "?" + url_query
|
||||
|
||||
return method, url, header_params, body, post_params
|
||||
|
||||
|
||||
def call_api(
|
||||
self,
|
||||
method,
|
||||
url,
|
||||
header_params=None,
|
||||
body=None,
|
||||
post_params=None,
|
||||
_request_timeout=None
|
||||
) -> rest.RESTResponse:
|
||||
"""Makes the HTTP request (synchronous)
|
||||
:param method: Method to call.
|
||||
:param url: Path to method endpoint.
|
||||
:param header_params: Header parameters to be
|
||||
placed in the request header.
|
||||
:param body: Request body.
|
||||
:param post_params dict: Request post form parameters,
|
||||
for `application/x-www-form-urlencoded`, `multipart/form-data`.
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
:return: RESTResponse
|
||||
"""
|
||||
|
||||
try:
|
||||
# perform request and return response
|
||||
response_data = self.rest_client.request(
|
||||
method, url,
|
||||
headers=header_params,
|
||||
body=body, post_params=post_params,
|
||||
_request_timeout=_request_timeout
|
||||
)
|
||||
|
||||
except ApiException as e:
|
||||
raise e
|
||||
|
||||
return response_data
|
||||
|
||||
def response_deserialize(
|
||||
self,
|
||||
response_data: rest.RESTResponse,
|
||||
response_types_map: Optional[Dict[str, ApiResponseT]]=None
|
||||
) -> ApiResponse[ApiResponseT]:
|
||||
"""Deserializes response into an object.
|
||||
:param response_data: RESTResponse object to be deserialized.
|
||||
:param response_types_map: dict of response types.
|
||||
:return: ApiResponse
|
||||
"""
|
||||
|
||||
msg = "RESTResponse.read() must be called before passing it to response_deserialize()"
|
||||
assert response_data.data is not None, msg
|
||||
|
||||
response_type = response_types_map.get(str(response_data.status), None)
|
||||
if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
|
||||
# if not found, look for '1XX', '2XX', etc.
|
||||
response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
|
||||
|
||||
# deserialize response data
|
||||
response_text = None
|
||||
return_data = None
|
||||
try:
|
||||
if response_type == "bytearray":
|
||||
return_data = response_data.data
|
||||
elif response_type == "file":
|
||||
return_data = self.__deserialize_file(response_data)
|
||||
elif response_type is not None:
|
||||
match = None
|
||||
content_type = response_data.getheader('content-type')
|
||||
if content_type is not None:
|
||||
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
|
||||
encoding = match.group(1) if match else "utf-8"
|
||||
response_text = response_data.data.decode(encoding)
|
||||
return_data = self.deserialize(response_text, response_type)
|
||||
finally:
|
||||
if not 200 <= response_data.status <= 299:
|
||||
raise ApiException.from_response(
|
||||
http_resp=response_data,
|
||||
body=response_text,
|
||||
data=return_data,
|
||||
)
|
||||
|
||||
return ApiResponse(
|
||||
status_code = response_data.status,
|
||||
data = return_data,
|
||||
headers = response_data.getheaders(),
|
||||
raw_data = response_data.data
|
||||
)
|
||||
|
||||
def sanitize_for_serialization(self, obj):
|
||||
"""Builds a JSON POST object.
|
||||
|
||||
If obj is None, return None.
|
||||
If obj is str, int, long, float, bool, return directly.
|
||||
If obj is datetime.datetime, datetime.date
|
||||
convert to string in iso8601 format.
|
||||
If obj is list, sanitize each element in the list.
|
||||
If obj is dict, return the dict.
|
||||
If obj is OpenAPI model, return the properties dict.
|
||||
|
||||
:param obj: The data to serialize.
|
||||
:return: The serialized form of data.
|
||||
"""
|
||||
if obj is None:
|
||||
return None
|
||||
elif isinstance(obj, self.PRIMITIVE_TYPES):
|
||||
return obj
|
||||
elif isinstance(obj, list):
|
||||
return [
|
||||
self.sanitize_for_serialization(sub_obj) for sub_obj in obj
|
||||
]
|
||||
elif isinstance(obj, tuple):
|
||||
return tuple(
|
||||
self.sanitize_for_serialization(sub_obj) for sub_obj in obj
|
||||
)
|
||||
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
||||
return obj.isoformat()
|
||||
|
||||
elif isinstance(obj, dict):
|
||||
obj_dict = obj
|
||||
else:
|
||||
# Convert model obj to dict except
|
||||
# attributes `openapi_types`, `attribute_map`
|
||||
# and attributes which value is not None.
|
||||
# Convert attribute name to json key in
|
||||
# model definition for request.
|
||||
obj_dict = obj.to_dict()
|
||||
|
||||
return {
|
||||
key: self.sanitize_for_serialization(val)
|
||||
for key, val in obj_dict.items()
|
||||
}
|
||||
|
||||
def deserialize(self, response_text, response_type):
|
||||
"""Deserializes response into an object.
|
||||
|
||||
:param response: RESTResponse object to be deserialized.
|
||||
:param response_type: class literal for
|
||||
deserialized object, or string of class name.
|
||||
|
||||
:return: deserialized object.
|
||||
"""
|
||||
|
||||
# fetch data from response object
|
||||
try:
|
||||
data = json.loads(response_text)
|
||||
except ValueError:
|
||||
data = response_text
|
||||
|
||||
return self.__deserialize(data, response_type)
|
||||
|
||||
def __deserialize(self, data, klass):
|
||||
"""Deserializes dict, list, str into an object.
|
||||
|
||||
:param data: dict, list or str.
|
||||
:param klass: class literal, or string of class name.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if isinstance(klass, str):
|
||||
if klass.startswith('List['):
|
||||
m = re.match(r'List\[(.*)]', klass)
|
||||
assert m is not None, "Malformed List type definition"
|
||||
sub_kls = m.group(1)
|
||||
return [self.__deserialize(sub_data, sub_kls)
|
||||
for sub_data in data]
|
||||
|
||||
if klass.startswith('Dict['):
|
||||
m = re.match(r'Dict\[([^,]*), (.*)]', klass)
|
||||
assert m is not None, "Malformed Dict type definition"
|
||||
sub_kls = m.group(2)
|
||||
return {k: self.__deserialize(v, sub_kls)
|
||||
for k, v in data.items()}
|
||||
|
||||
# convert str to class
|
||||
if klass in self.NATIVE_TYPES_MAPPING:
|
||||
klass = self.NATIVE_TYPES_MAPPING[klass]
|
||||
else:
|
||||
klass = getattr(openapi_client.models, klass)
|
||||
|
||||
if klass in self.PRIMITIVE_TYPES:
|
||||
return self.__deserialize_primitive(data, klass)
|
||||
elif klass == object:
|
||||
return self.__deserialize_object(data)
|
||||
elif klass == datetime.date:
|
||||
return self.__deserialize_date(data)
|
||||
elif klass == datetime.datetime:
|
||||
return self.__deserialize_datetime(data)
|
||||
elif issubclass(klass, Enum):
|
||||
return self.__deserialize_enum(data, klass)
|
||||
else:
|
||||
return self.__deserialize_model(data, klass)
|
||||
|
||||
def parameters_to_tuples(self, params, collection_formats):
|
||||
"""Get parameters as list of tuples, formatting collections.
|
||||
|
||||
:param params: Parameters as dict or list of two-tuples
|
||||
:param dict collection_formats: Parameter collection formats
|
||||
:return: Parameters as list of tuples, collections formatted
|
||||
"""
|
||||
new_params: List[Tuple[str, str]] = []
|
||||
if collection_formats is None:
|
||||
collection_formats = {}
|
||||
for k, v in params.items() if isinstance(params, dict) else params:
|
||||
if k in collection_formats:
|
||||
collection_format = collection_formats[k]
|
||||
if collection_format == 'multi':
|
||||
new_params.extend((k, value) for value in v)
|
||||
else:
|
||||
if collection_format == 'ssv':
|
||||
delimiter = ' '
|
||||
elif collection_format == 'tsv':
|
||||
delimiter = '\t'
|
||||
elif collection_format == 'pipes':
|
||||
delimiter = '|'
|
||||
else: # csv is the default
|
||||
delimiter = ','
|
||||
new_params.append(
|
||||
(k, delimiter.join(str(value) for value in v)))
|
||||
else:
|
||||
new_params.append((k, v))
|
||||
return new_params
|
||||
|
||||
def parameters_to_url_query(self, params, collection_formats):
|
||||
"""Get parameters as list of tuples, formatting collections.
|
||||
|
||||
:param params: Parameters as dict or list of two-tuples
|
||||
:param dict collection_formats: Parameter collection formats
|
||||
:return: URL query string (e.g. a=Hello%20World&b=123)
|
||||
"""
|
||||
new_params: List[Tuple[str, str]] = []
|
||||
if collection_formats is None:
|
||||
collection_formats = {}
|
||||
for k, v in params.items() if isinstance(params, dict) else params:
|
||||
if isinstance(v, bool):
|
||||
v = str(v).lower()
|
||||
if isinstance(v, (int, float)):
|
||||
v = str(v)
|
||||
if isinstance(v, dict):
|
||||
v = json.dumps(v)
|
||||
|
||||
if k in collection_formats:
|
||||
collection_format = collection_formats[k]
|
||||
if collection_format == 'multi':
|
||||
new_params.extend((k, str(value)) for value in v)
|
||||
else:
|
||||
if collection_format == 'ssv':
|
||||
delimiter = ' '
|
||||
elif collection_format == 'tsv':
|
||||
delimiter = '\t'
|
||||
elif collection_format == 'pipes':
|
||||
delimiter = '|'
|
||||
else: # csv is the default
|
||||
delimiter = ','
|
||||
new_params.append(
|
||||
(k, delimiter.join(quote(str(value)) for value in v))
|
||||
)
|
||||
else:
|
||||
new_params.append((k, quote(str(v))))
|
||||
|
||||
return "&".join(["=".join(map(str, item)) for item in new_params])
|
||||
|
||||
def files_parameters(self, files=None):
|
||||
"""Builds form parameters.
|
||||
|
||||
:param files: File parameters.
|
||||
:return: Form parameters with files.
|
||||
"""
|
||||
params = []
|
||||
|
||||
if files:
|
||||
for k, v in files.items():
|
||||
if not v:
|
||||
continue
|
||||
file_names = v if type(v) is list else [v]
|
||||
for n in file_names:
|
||||
with open(n, 'rb') as f:
|
||||
filename = os.path.basename(f.name)
|
||||
filedata = f.read()
|
||||
mimetype = (
|
||||
mimetypes.guess_type(filename)[0]
|
||||
or 'application/octet-stream'
|
||||
)
|
||||
params.append(
|
||||
tuple([k, tuple([filename, filedata, mimetype])])
|
||||
)
|
||||
|
||||
return params
|
||||
|
||||
def select_header_accept(self, accepts: List[str]) -> Optional[str]:
|
||||
"""Returns `Accept` based on an array of accepts provided.
|
||||
|
||||
:param accepts: List of headers.
|
||||
:return: Accept (e.g. application/json).
|
||||
"""
|
||||
if not accepts:
|
||||
return None
|
||||
|
||||
for accept in accepts:
|
||||
if re.search('json', accept, re.IGNORECASE):
|
||||
return accept
|
||||
|
||||
return accepts[0]
|
||||
|
||||
def select_header_content_type(self, content_types):
|
||||
"""Returns `Content-Type` based on an array of content_types provided.
|
||||
|
||||
:param content_types: List of content-types.
|
||||
:return: Content-Type (e.g. application/json).
|
||||
"""
|
||||
if not content_types:
|
||||
return None
|
||||
|
||||
for content_type in content_types:
|
||||
if re.search('json', content_type, re.IGNORECASE):
|
||||
return content_type
|
||||
|
||||
return content_types[0]
|
||||
|
||||
def update_params_for_auth(
|
||||
self,
|
||||
headers,
|
||||
queries,
|
||||
auth_settings,
|
||||
resource_path,
|
||||
method,
|
||||
body,
|
||||
request_auth=None
|
||||
) -> None:
|
||||
"""Updates header and query params based on authentication setting.
|
||||
|
||||
:param headers: Header parameters dict to be updated.
|
||||
:param queries: Query parameters tuple list to be updated.
|
||||
:param auth_settings: Authentication setting identifiers list.
|
||||
:resource_path: A string representation of the HTTP request resource path.
|
||||
:method: A string representation of the HTTP request method.
|
||||
:body: A object representing the body of the HTTP request.
|
||||
The object type is the return value of sanitize_for_serialization().
|
||||
:param request_auth: if set, the provided settings will
|
||||
override the token in the configuration.
|
||||
"""
|
||||
if not auth_settings:
|
||||
return
|
||||
|
||||
if request_auth:
|
||||
self._apply_auth_params(
|
||||
headers,
|
||||
queries,
|
||||
resource_path,
|
||||
method,
|
||||
body,
|
||||
request_auth
|
||||
)
|
||||
else:
|
||||
for auth in auth_settings:
|
||||
auth_setting = self.configuration.auth_settings().get(auth)
|
||||
if auth_setting:
|
||||
self._apply_auth_params(
|
||||
headers,
|
||||
queries,
|
||||
resource_path,
|
||||
method,
|
||||
body,
|
||||
auth_setting
|
||||
)
|
||||
|
||||
def _apply_auth_params(
|
||||
self,
|
||||
headers,
|
||||
queries,
|
||||
resource_path,
|
||||
method,
|
||||
body,
|
||||
auth_setting
|
||||
) -> None:
|
||||
"""Updates the request parameters based on a single auth_setting
|
||||
|
||||
:param headers: Header parameters dict to be updated.
|
||||
:param queries: Query parameters tuple list to be updated.
|
||||
:resource_path: A string representation of the HTTP request resource path.
|
||||
:method: A string representation of the HTTP request method.
|
||||
:body: A object representing the body of the HTTP request.
|
||||
The object type is the return value of sanitize_for_serialization().
|
||||
:param auth_setting: auth settings for the endpoint
|
||||
"""
|
||||
if auth_setting['in'] == 'cookie':
|
||||
headers['Cookie'] = auth_setting['value']
|
||||
elif auth_setting['in'] == 'header':
|
||||
if auth_setting['type'] != 'http-signature':
|
||||
headers[auth_setting['key']] = auth_setting['value']
|
||||
elif auth_setting['in'] == 'query':
|
||||
queries.append((auth_setting['key'], auth_setting['value']))
|
||||
else:
|
||||
raise ApiValueError(
|
||||
'Authentication token must be in `query` or `header`'
|
||||
)
|
||||
|
||||
def __deserialize_file(self, response):
|
||||
"""Deserializes body to file
|
||||
|
||||
Saves response body into a file in a temporary folder,
|
||||
using the filename from the `Content-Disposition` header if provided.
|
||||
|
||||
handle file downloading
|
||||
save response body into a tmp file and return the instance
|
||||
|
||||
:param response: RESTResponse.
|
||||
:return: file path.
|
||||
"""
|
||||
fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
|
||||
os.close(fd)
|
||||
os.remove(path)
|
||||
|
||||
content_disposition = response.getheader("Content-Disposition")
|
||||
if content_disposition:
|
||||
m = re.search(
|
||||
r'filename=[\'"]?([^\'"\s]+)[\'"]?',
|
||||
content_disposition
|
||||
)
|
||||
assert m is not None, "Unexpected 'content-disposition' header value"
|
||||
filename = m.group(1)
|
||||
path = os.path.join(os.path.dirname(path), filename)
|
||||
|
||||
with open(path, "wb") as f:
|
||||
f.write(response.data)
|
||||
|
||||
return path
|
||||
|
||||
def __deserialize_primitive(self, data, klass):
|
||||
"""Deserializes string to primitive type.
|
||||
|
||||
:param data: str.
|
||||
:param klass: class literal.
|
||||
|
||||
:return: int, long, float, str, bool.
|
||||
"""
|
||||
try:
|
||||
return klass(data)
|
||||
except UnicodeEncodeError:
|
||||
return str(data)
|
||||
except TypeError:
|
||||
return data
|
||||
|
||||
def __deserialize_object(self, value):
|
||||
"""Return an original value.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
return value
|
||||
|
||||
def __deserialize_date(self, string):
|
||||
"""Deserializes string to date.
|
||||
|
||||
:param string: str.
|
||||
:return: date.
|
||||
"""
|
||||
try:
|
||||
return parse(string).date()
|
||||
except ImportError:
|
||||
return string
|
||||
except ValueError:
|
||||
raise rest.ApiException(
|
||||
status=0,
|
||||
reason="Failed to parse `{0}` as date object".format(string)
|
||||
)
|
||||
|
||||
def __deserialize_datetime(self, string):
|
||||
"""Deserializes string to datetime.
|
||||
|
||||
The string should be in iso8601 datetime format.
|
||||
|
||||
:param string: str.
|
||||
:return: datetime.
|
||||
"""
|
||||
try:
|
||||
return parse(string)
|
||||
except ImportError:
|
||||
return string
|
||||
except ValueError:
|
||||
raise rest.ApiException(
|
||||
status=0,
|
||||
reason=(
|
||||
"Failed to parse `{0}` as datetime object"
|
||||
.format(string)
|
||||
)
|
||||
)
|
||||
|
||||
def __deserialize_enum(self, data, klass):
|
||||
"""Deserializes primitive type to enum.
|
||||
|
||||
:param data: primitive type.
|
||||
:param klass: class literal.
|
||||
:return: enum value.
|
||||
"""
|
||||
try:
|
||||
return klass(data)
|
||||
except ValueError:
|
||||
raise rest.ApiException(
|
||||
status=0,
|
||||
reason=(
|
||||
"Failed to parse `{0}` as `{1}`"
|
||||
.format(data, klass)
|
||||
)
|
||||
)
|
||||
|
||||
def __deserialize_model(self, data, klass):
|
||||
"""Deserializes list or dict to model.
|
||||
|
||||
:param data: dict, list.
|
||||
:param klass: class literal.
|
||||
:return: model object.
|
||||
"""
|
||||
|
||||
return klass.from_dict(data)
|
||||
21
demo_server/demo_client/openapi_client/api_response.py
Normal file
21
demo_server/demo_client/openapi_client/api_response.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""API response object."""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Optional, Generic, Mapping, TypeVar
|
||||
from pydantic import Field, StrictInt, StrictBytes, BaseModel
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
class ApiResponse(BaseModel, Generic[T]):
|
||||
"""
|
||||
API response object
|
||||
"""
|
||||
|
||||
status_code: StrictInt = Field(description="HTTP status code")
|
||||
headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers")
|
||||
data: T = Field(description="Deserialized data given the data type")
|
||||
raw_data: StrictBytes = Field(description="Raw data (HTTP response body)")
|
||||
|
||||
model_config = {
|
||||
"arbitrary_types_allowed": True
|
||||
}
|
||||
436
demo_server/demo_client/openapi_client/configuration.py
Normal file
436
demo_server/demo_client/openapi_client/configuration.py
Normal file
@@ -0,0 +1,436 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import copy
|
||||
import logging
|
||||
from logging import FileHandler
|
||||
import multiprocessing
|
||||
import sys
|
||||
from typing import Optional
|
||||
import urllib3
|
||||
|
||||
import http.client as httplib
|
||||
|
||||
JSON_SCHEMA_VALIDATION_KEYWORDS = {
|
||||
'multipleOf', 'maximum', 'exclusiveMaximum',
|
||||
'minimum', 'exclusiveMinimum', 'maxLength',
|
||||
'minLength', 'pattern', 'maxItems', 'minItems'
|
||||
}
|
||||
|
||||
class Configuration:
|
||||
"""This class contains various settings of the API client.
|
||||
|
||||
:param host: Base url.
|
||||
:param api_key: Dict to store API key(s).
|
||||
Each entry in the dict specifies an API key.
|
||||
The dict key is the name of the security scheme in the OAS specification.
|
||||
The dict value is the API key secret.
|
||||
:param api_key_prefix: Dict to store API prefix (e.g. Bearer).
|
||||
The dict key is the name of the security scheme in the OAS specification.
|
||||
The dict value is an API key prefix when generating the auth data.
|
||||
:param username: Username for HTTP basic authentication.
|
||||
:param password: Password for HTTP basic authentication.
|
||||
:param access_token: Access token.
|
||||
:param server_index: Index to servers configuration.
|
||||
:param server_variables: Mapping with string values to replace variables in
|
||||
templated server configuration. The validation of enums is performed for
|
||||
variables with defined enum values before.
|
||||
:param server_operation_index: Mapping from operation ID to an index to server
|
||||
configuration.
|
||||
:param server_operation_variables: Mapping from operation ID to a mapping with
|
||||
string values to replace variables in templated server configuration.
|
||||
The validation of enums is performed for variables with defined enum
|
||||
values before.
|
||||
:param ssl_ca_cert: str - the path to a file of concatenated CA certificates
|
||||
in PEM format.
|
||||
|
||||
"""
|
||||
|
||||
_default = None
|
||||
|
||||
def __init__(self, host=None,
|
||||
api_key=None, api_key_prefix=None,
|
||||
username=None, password=None,
|
||||
access_token=None,
|
||||
server_index=None, server_variables=None,
|
||||
server_operation_index=None, server_operation_variables=None,
|
||||
ssl_ca_cert=None,
|
||||
) -> None:
|
||||
"""Constructor
|
||||
"""
|
||||
self._base_path = "http://localhost" if host is None else host
|
||||
"""Default Base url
|
||||
"""
|
||||
self.server_index = 0 if server_index is None and host is None else server_index
|
||||
self.server_operation_index = server_operation_index or {}
|
||||
"""Default server index
|
||||
"""
|
||||
self.server_variables = server_variables or {}
|
||||
self.server_operation_variables = server_operation_variables or {}
|
||||
"""Default server variables
|
||||
"""
|
||||
self.temp_folder_path = None
|
||||
"""Temp file folder for downloading files
|
||||
"""
|
||||
# Authentication Settings
|
||||
self.api_key = {}
|
||||
if api_key:
|
||||
self.api_key = api_key
|
||||
"""dict to store API key(s)
|
||||
"""
|
||||
self.api_key_prefix = {}
|
||||
if api_key_prefix:
|
||||
self.api_key_prefix = api_key_prefix
|
||||
"""dict to store API prefix (e.g. Bearer)
|
||||
"""
|
||||
self.refresh_api_key_hook = None
|
||||
"""function hook to refresh API key if expired
|
||||
"""
|
||||
self.username = username
|
||||
"""Username for HTTP basic authentication
|
||||
"""
|
||||
self.password = password
|
||||
"""Password for HTTP basic authentication
|
||||
"""
|
||||
self.access_token = access_token
|
||||
"""Access token
|
||||
"""
|
||||
self.logger = {}
|
||||
"""Logging Settings
|
||||
"""
|
||||
self.logger["package_logger"] = logging.getLogger("openapi_client")
|
||||
self.logger["urllib3_logger"] = logging.getLogger("urllib3")
|
||||
self.logger_format = '%(asctime)s %(levelname)s %(message)s'
|
||||
"""Log format
|
||||
"""
|
||||
self.logger_stream_handler = None
|
||||
"""Log stream handler
|
||||
"""
|
||||
self.logger_file_handler: Optional[FileHandler] = None
|
||||
"""Log file handler
|
||||
"""
|
||||
self.logger_file = None
|
||||
"""Debug file location
|
||||
"""
|
||||
self.debug = False
|
||||
"""Debug switch
|
||||
"""
|
||||
|
||||
self.verify_ssl = True
|
||||
"""SSL/TLS verification
|
||||
Set this to false to skip verifying SSL certificate when calling API
|
||||
from https server.
|
||||
"""
|
||||
self.ssl_ca_cert = ssl_ca_cert
|
||||
"""Set this to customize the certificate file to verify the peer.
|
||||
"""
|
||||
self.cert_file = None
|
||||
"""client certificate file
|
||||
"""
|
||||
self.key_file = None
|
||||
"""client key file
|
||||
"""
|
||||
self.assert_hostname = None
|
||||
"""Set this to True/False to enable/disable SSL hostname verification.
|
||||
"""
|
||||
self.tls_server_name = None
|
||||
"""SSL/TLS Server Name Indication (SNI)
|
||||
Set this to the SNI value expected by the server.
|
||||
"""
|
||||
|
||||
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
|
||||
"""urllib3 connection pool's maximum number of connections saved
|
||||
per pool. urllib3 uses 1 connection as default value, but this is
|
||||
not the best value when you are making a lot of possibly parallel
|
||||
requests to the same host, which is often the case here.
|
||||
cpu_count * 5 is used as default value to increase performance.
|
||||
"""
|
||||
|
||||
self.proxy: Optional[str] = None
|
||||
"""Proxy URL
|
||||
"""
|
||||
self.proxy_headers = None
|
||||
"""Proxy headers
|
||||
"""
|
||||
self.safe_chars_for_path_param = ''
|
||||
"""Safe chars for path_param
|
||||
"""
|
||||
self.retries = None
|
||||
"""Adding retries to override urllib3 default value 3
|
||||
"""
|
||||
# Enable client side validation
|
||||
self.client_side_validation = True
|
||||
|
||||
self.socket_options = None
|
||||
"""Options to pass down to the underlying urllib3 socket
|
||||
"""
|
||||
|
||||
self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z"
|
||||
"""datetime format
|
||||
"""
|
||||
|
||||
self.date_format = "%Y-%m-%d"
|
||||
"""date format
|
||||
"""
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
cls = self.__class__
|
||||
result = cls.__new__(cls)
|
||||
memo[id(self)] = result
|
||||
for k, v in self.__dict__.items():
|
||||
if k not in ('logger', 'logger_file_handler'):
|
||||
setattr(result, k, copy.deepcopy(v, memo))
|
||||
# shallow copy of loggers
|
||||
result.logger = copy.copy(self.logger)
|
||||
# use setters to configure loggers
|
||||
result.logger_file = self.logger_file
|
||||
result.debug = self.debug
|
||||
return result
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
object.__setattr__(self, name, value)
|
||||
|
||||
@classmethod
|
||||
def set_default(cls, default):
|
||||
"""Set default instance of configuration.
|
||||
|
||||
It stores default configuration, which can be
|
||||
returned by get_default_copy method.
|
||||
|
||||
:param default: object of Configuration
|
||||
"""
|
||||
cls._default = default
|
||||
|
||||
@classmethod
|
||||
def get_default_copy(cls):
|
||||
"""Deprecated. Please use `get_default` instead.
|
||||
|
||||
Deprecated. Please use `get_default` instead.
|
||||
|
||||
:return: The configuration object.
|
||||
"""
|
||||
return cls.get_default()
|
||||
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
"""Return the default configuration.
|
||||
|
||||
This method returns newly created, based on default constructor,
|
||||
object of Configuration class or returns a copy of default
|
||||
configuration.
|
||||
|
||||
:return: The configuration object.
|
||||
"""
|
||||
if cls._default is None:
|
||||
cls._default = Configuration()
|
||||
return cls._default
|
||||
|
||||
@property
|
||||
def logger_file(self):
|
||||
"""The logger file.
|
||||
|
||||
If the logger_file is None, then add stream handler and remove file
|
||||
handler. Otherwise, add file handler and remove stream handler.
|
||||
|
||||
:param value: The logger_file path.
|
||||
:type: str
|
||||
"""
|
||||
return self.__logger_file
|
||||
|
||||
@logger_file.setter
|
||||
def logger_file(self, value):
|
||||
"""The logger file.
|
||||
|
||||
If the logger_file is None, then add stream handler and remove file
|
||||
handler. Otherwise, add file handler and remove stream handler.
|
||||
|
||||
:param value: The logger_file path.
|
||||
:type: str
|
||||
"""
|
||||
self.__logger_file = value
|
||||
if self.__logger_file:
|
||||
# If set logging file,
|
||||
# then add file handler and remove stream handler.
|
||||
self.logger_file_handler = logging.FileHandler(self.__logger_file)
|
||||
self.logger_file_handler.setFormatter(self.logger_formatter)
|
||||
for _, logger in self.logger.items():
|
||||
logger.addHandler(self.logger_file_handler)
|
||||
|
||||
@property
|
||||
def debug(self):
|
||||
"""Debug status
|
||||
|
||||
:param value: The debug status, True or False.
|
||||
:type: bool
|
||||
"""
|
||||
return self.__debug
|
||||
|
||||
@debug.setter
|
||||
def debug(self, value):
|
||||
"""Debug status
|
||||
|
||||
:param value: The debug status, True or False.
|
||||
:type: bool
|
||||
"""
|
||||
self.__debug = value
|
||||
if self.__debug:
|
||||
# if debug status is True, turn on debug logging
|
||||
for _, logger in self.logger.items():
|
||||
logger.setLevel(logging.DEBUG)
|
||||
# turn on httplib debug
|
||||
httplib.HTTPConnection.debuglevel = 1
|
||||
else:
|
||||
# if debug status is False, turn off debug logging,
|
||||
# setting log level to default `logging.WARNING`
|
||||
for _, logger in self.logger.items():
|
||||
logger.setLevel(logging.WARNING)
|
||||
# turn off httplib debug
|
||||
httplib.HTTPConnection.debuglevel = 0
|
||||
|
||||
@property
|
||||
def logger_format(self):
|
||||
"""The logger format.
|
||||
|
||||
The logger_formatter will be updated when sets logger_format.
|
||||
|
||||
:param value: The format string.
|
||||
:type: str
|
||||
"""
|
||||
return self.__logger_format
|
||||
|
||||
@logger_format.setter
|
||||
def logger_format(self, value):
|
||||
"""The logger format.
|
||||
|
||||
The logger_formatter will be updated when sets logger_format.
|
||||
|
||||
:param value: The format string.
|
||||
:type: str
|
||||
"""
|
||||
self.__logger_format = value
|
||||
self.logger_formatter = logging.Formatter(self.__logger_format)
|
||||
|
||||
def get_api_key_with_prefix(self, identifier, alias=None):
|
||||
"""Gets API key (with prefix if set).
|
||||
|
||||
:param identifier: The identifier of apiKey.
|
||||
:param alias: The alternative identifier of apiKey.
|
||||
:return: The token for api key authentication.
|
||||
"""
|
||||
if self.refresh_api_key_hook is not None:
|
||||
self.refresh_api_key_hook(self)
|
||||
key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None)
|
||||
if key:
|
||||
prefix = self.api_key_prefix.get(identifier)
|
||||
if prefix:
|
||||
return "%s %s" % (prefix, key)
|
||||
else:
|
||||
return key
|
||||
|
||||
def get_basic_auth_token(self):
|
||||
"""Gets HTTP basic authentication header (string).
|
||||
|
||||
:return: The token for basic HTTP authentication.
|
||||
"""
|
||||
username = ""
|
||||
if self.username is not None:
|
||||
username = self.username
|
||||
password = ""
|
||||
if self.password is not None:
|
||||
password = self.password
|
||||
return urllib3.util.make_headers(
|
||||
basic_auth=username + ':' + password
|
||||
).get('authorization')
|
||||
|
||||
def auth_settings(self):
|
||||
"""Gets Auth Settings dict for api client.
|
||||
|
||||
:return: The Auth Settings information dict.
|
||||
"""
|
||||
auth = {}
|
||||
return auth
|
||||
|
||||
def to_debug_report(self):
|
||||
"""Gets the essential information for debugging.
|
||||
|
||||
:return: The report for debugging.
|
||||
"""
|
||||
return "Python SDK Debug Report:\n"\
|
||||
"OS: {env}\n"\
|
||||
"Python Version: {pyversion}\n"\
|
||||
"Version of the API: 0.0.1\n"\
|
||||
"SDK Package Version: 1.0.0".\
|
||||
format(env=sys.platform, pyversion=sys.version)
|
||||
|
||||
def get_host_settings(self):
|
||||
"""Gets an array of host settings
|
||||
|
||||
:return: An array of host settings
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'url': "",
|
||||
'description': "No description provided",
|
||||
}
|
||||
]
|
||||
|
||||
def get_host_from_settings(self, index, variables=None, servers=None):
|
||||
"""Gets host URL based on the index and variables
|
||||
:param index: array index of the host settings
|
||||
:param variables: hash of variable and the corresponding value
|
||||
:param servers: an array of host settings or None
|
||||
:return: URL based on host settings
|
||||
"""
|
||||
if index is None:
|
||||
return self._base_path
|
||||
|
||||
variables = {} if variables is None else variables
|
||||
servers = self.get_host_settings() if servers is None else servers
|
||||
|
||||
try:
|
||||
server = servers[index]
|
||||
except IndexError:
|
||||
raise ValueError(
|
||||
"Invalid index {0} when selecting the host settings. "
|
||||
"Must be less than {1}".format(index, len(servers)))
|
||||
|
||||
url = server['url']
|
||||
|
||||
# go through variables and replace placeholders
|
||||
for variable_name, variable in server.get('variables', {}).items():
|
||||
used_value = variables.get(
|
||||
variable_name, variable['default_value'])
|
||||
|
||||
if 'enum_values' in variable \
|
||||
and used_value not in variable['enum_values']:
|
||||
raise ValueError(
|
||||
"The variable `{0}` in the host URL has invalid value "
|
||||
"{1}. Must be {2}.".format(
|
||||
variable_name, variables[variable_name],
|
||||
variable['enum_values']))
|
||||
|
||||
url = url.replace("{" + variable_name + "}", used_value)
|
||||
|
||||
return url
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
"""Return generated host."""
|
||||
return self.get_host_from_settings(self.server_index, variables=self.server_variables)
|
||||
|
||||
@host.setter
|
||||
def host(self, value):
|
||||
"""Fix base path."""
|
||||
self._base_path = value
|
||||
self.server_index = None
|
||||
199
demo_server/demo_client/openapi_client/exceptions.py
Normal file
199
demo_server/demo_client/openapi_client/exceptions.py
Normal file
@@ -0,0 +1,199 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
from typing import Any, Optional
|
||||
from typing_extensions import Self
|
||||
|
||||
class OpenApiException(Exception):
|
||||
"""The base exception class for all OpenAPIExceptions"""
|
||||
|
||||
|
||||
class ApiTypeError(OpenApiException, TypeError):
|
||||
def __init__(self, msg, path_to_item=None, valid_classes=None,
|
||||
key_type=None) -> None:
|
||||
""" Raises an exception for TypeErrors
|
||||
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (list): a list of keys an indices to get to the
|
||||
current_item
|
||||
None if unset
|
||||
valid_classes (tuple): the primitive classes that current item
|
||||
should be an instance of
|
||||
None if unset
|
||||
key_type (bool): False if our value is a value in a dict
|
||||
True if it is a key in a dict
|
||||
False if our item is an item in a list
|
||||
None if unset
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
self.valid_classes = valid_classes
|
||||
self.key_type = key_type
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiTypeError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiValueError(OpenApiException, ValueError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (list) the path to the exception in the
|
||||
received_data dict. None if unset
|
||||
"""
|
||||
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiValueError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiAttributeError(OpenApiException, AttributeError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Raised when an attribute reference or assignment fails.
|
||||
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (None/list) the path to the exception in the
|
||||
received_data dict
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiAttributeError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiKeyError(OpenApiException, KeyError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (None/list) the path to the exception in the
|
||||
received_data dict
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiKeyError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiException(OpenApiException):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
status=None,
|
||||
reason=None,
|
||||
http_resp=None,
|
||||
*,
|
||||
body: Optional[str] = None,
|
||||
data: Optional[Any] = None,
|
||||
) -> None:
|
||||
self.status = status
|
||||
self.reason = reason
|
||||
self.body = body
|
||||
self.data = data
|
||||
self.headers = None
|
||||
|
||||
if http_resp:
|
||||
if self.status is None:
|
||||
self.status = http_resp.status
|
||||
if self.reason is None:
|
||||
self.reason = http_resp.reason
|
||||
if self.body is None:
|
||||
try:
|
||||
self.body = http_resp.data.decode('utf-8')
|
||||
except Exception:
|
||||
pass
|
||||
self.headers = http_resp.getheaders()
|
||||
|
||||
@classmethod
|
||||
def from_response(
|
||||
cls,
|
||||
*,
|
||||
http_resp,
|
||||
body: Optional[str],
|
||||
data: Optional[Any],
|
||||
) -> Self:
|
||||
if http_resp.status == 400:
|
||||
raise BadRequestException(http_resp=http_resp, body=body, data=data)
|
||||
|
||||
if http_resp.status == 401:
|
||||
raise UnauthorizedException(http_resp=http_resp, body=body, data=data)
|
||||
|
||||
if http_resp.status == 403:
|
||||
raise ForbiddenException(http_resp=http_resp, body=body, data=data)
|
||||
|
||||
if http_resp.status == 404:
|
||||
raise NotFoundException(http_resp=http_resp, body=body, data=data)
|
||||
|
||||
if 500 <= http_resp.status <= 599:
|
||||
raise ServiceException(http_resp=http_resp, body=body, data=data)
|
||||
raise ApiException(http_resp=http_resp, body=body, data=data)
|
||||
|
||||
def __str__(self):
|
||||
"""Custom error messages for exception"""
|
||||
error_message = "({0})\n"\
|
||||
"Reason: {1}\n".format(self.status, self.reason)
|
||||
if self.headers:
|
||||
error_message += "HTTP response headers: {0}\n".format(
|
||||
self.headers)
|
||||
|
||||
if self.data or self.body:
|
||||
error_message += "HTTP response body: {0}\n".format(self.data or self.body)
|
||||
|
||||
return error_message
|
||||
|
||||
|
||||
class BadRequestException(ApiException):
|
||||
pass
|
||||
|
||||
|
||||
class NotFoundException(ApiException):
|
||||
pass
|
||||
|
||||
|
||||
class UnauthorizedException(ApiException):
|
||||
pass
|
||||
|
||||
|
||||
class ForbiddenException(ApiException):
|
||||
pass
|
||||
|
||||
|
||||
class ServiceException(ApiException):
|
||||
pass
|
||||
|
||||
|
||||
def render_path(path_to_item):
|
||||
"""Returns a string representation of a path"""
|
||||
result = ""
|
||||
for pth in path_to_item:
|
||||
if isinstance(pth, int):
|
||||
result += "[{0}]".format(pth)
|
||||
else:
|
||||
result += "['{0}']".format(pth)
|
||||
return result
|
||||
26
demo_server/demo_client/openapi_client/models/__init__.py
Normal file
26
demo_server/demo_client/openapi_client/models/__init__.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# coding: utf-8
|
||||
|
||||
# flake8: noqa
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
# import models into model package
|
||||
from openapi_client.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
from openapi_client.models.google_protobuf_any import GoogleProtobufAny
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
from openapi_client.models.ice_session_description import IceSessionDescription
|
||||
from openapi_client.models.knock import Knock
|
||||
from openapi_client.models.list_knocks_response import ListKnocksResponse
|
||||
from openapi_client.models.room import Room
|
||||
from openapi_client.models.server import Server
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.status import Status
|
||||
@@ -0,0 +1,95 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class ClaimIceCandidatesResponse(BaseModel):
|
||||
"""
|
||||
ClaimIceCandidatesResponse
|
||||
""" # noqa: E501
|
||||
ice_candidates: Optional[List[IceCandidate]] = Field(default=None, alias="iceCandidates")
|
||||
__properties: ClassVar[List[str]] = ["iceCandidates"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of ClaimIceCandidatesResponse from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in ice_candidates (list)
|
||||
_items = []
|
||||
if self.ice_candidates:
|
||||
for _item in self.ice_candidates:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['iceCandidates'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of ClaimIceCandidatesResponse from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"iceCandidates": [IceCandidate.from_dict(_item) for _item in obj["iceCandidates"]] if obj.get("iceCandidates") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class GoogleProtobufAny(BaseModel):
|
||||
"""
|
||||
Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
|
||||
""" # noqa: E501
|
||||
type: Optional[StrictStr] = Field(default=None, description="The type of the serialized message.", alias="@type")
|
||||
additional_properties: Dict[str, Any] = {}
|
||||
__properties: ClassVar[List[str]] = ["@type"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of GoogleProtobufAny from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
* Fields in `self.additional_properties` are added to the output dict.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
"additional_properties",
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# puts key-value pairs in additional_properties in the top level
|
||||
if self.additional_properties is not None:
|
||||
for _key, _value in self.additional_properties.items():
|
||||
_dict[_key] = _value
|
||||
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of GoogleProtobufAny from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"@type": obj.get("@type")
|
||||
})
|
||||
# store additional fields in additional_properties
|
||||
for _key in obj.keys():
|
||||
if _key not in cls.__properties:
|
||||
_obj.additional_properties[_key] = obj.get(_key)
|
||||
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class IceCandidate(BaseModel):
|
||||
"""
|
||||
IceCandidate
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
candidate: Optional[StrictStr] = None
|
||||
sdp_mid: Optional[StrictStr] = Field(default=None, alias="sdpMid")
|
||||
sdp_line_index: Optional[StrictInt] = Field(default=None, alias="sdpLineIndex")
|
||||
username_fragment: Optional[StrictStr] = Field(default=None, alias="usernameFragment")
|
||||
__properties: ClassVar[List[str]] = ["name", "candidate", "sdpMid", "sdpLineIndex", "usernameFragment"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of IceCandidate from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of IceCandidate from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"candidate": obj.get("candidate"),
|
||||
"sdpMid": obj.get("sdpMid"),
|
||||
"sdpLineIndex": obj.get("sdpLineIndex"),
|
||||
"usernameFragment": obj.get("usernameFragment")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class IceSessionDescription(BaseModel):
|
||||
"""
|
||||
IceSessionDescription
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = Field(default=None, description="A unique identifier which can be used to send ICE candidates Maps to the session name")
|
||||
sdp_type: Optional[StrictStr] = Field(default=None, description="Used to construct the remote description in WebRTC", alias="sdpType")
|
||||
sdp: Optional[StrictStr] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "sdpType", "sdp"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of IceSessionDescription from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of IceSessionDescription from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"sdpType": obj.get("sdpType"),
|
||||
"sdp": obj.get("sdp")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
98
demo_server/demo_client/openapi_client/models/knock.py
Normal file
98
demo_server/demo_client/openapi_client/models/knock.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.ice_session_description import IceSessionDescription
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class Knock(BaseModel):
|
||||
"""
|
||||
Knock
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
offer: Optional[IceSessionDescription] = Field(default=None, description="The service being connected too")
|
||||
answer: Optional[IceSessionDescription] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "offer", "answer"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of Knock from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of offer
|
||||
if self.offer:
|
||||
_dict['offer'] = self.offer.to_dict()
|
||||
# override the default output from pydantic by calling `to_dict()` of answer
|
||||
if self.answer:
|
||||
_dict['answer'] = self.answer.to_dict()
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of Knock from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"offer": IceSessionDescription.from_dict(obj["offer"]) if obj.get("offer") is not None else None,
|
||||
"answer": IceSessionDescription.from_dict(obj["answer"]) if obj.get("answer") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.knock import Knock
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class ListKnocksResponse(BaseModel):
|
||||
"""
|
||||
ListKnocksResponse
|
||||
""" # noqa: E501
|
||||
knocks: Optional[List[Knock]] = None
|
||||
__properties: ClassVar[List[str]] = ["knocks"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of ListKnocksResponse from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in knocks (list)
|
||||
_items = []
|
||||
if self.knocks:
|
||||
for _item in self.knocks:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['knocks'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of ListKnocksResponse from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"knocks": [Knock.from_dict(_item) for _item in obj["knocks"]] if obj.get("knocks") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
99
demo_server/demo_client/openapi_client/models/room.py
Normal file
99
demo_server/demo_client/openapi_client/models/room.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.server import Server
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class Room(BaseModel):
|
||||
"""
|
||||
Room
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
display_name: Optional[StrictStr] = Field(default=None, alias="displayName")
|
||||
servers: Optional[List[Server]] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "displayName", "servers"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of Room from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in servers (list)
|
||||
_items = []
|
||||
if self.servers:
|
||||
for _item in self.servers:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['servers'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of Room from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"displayName": obj.get("displayName"),
|
||||
"servers": [Server.from_dict(_item) for _item in obj["servers"]] if obj.get("servers") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
103
demo_server/demo_client/openapi_client/models/server.py
Normal file
103
demo_server/demo_client/openapi_client/models/server.py
Normal file
@@ -0,0 +1,103 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.service import Service
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class Server(BaseModel):
|
||||
"""
|
||||
Server
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
rooms: Optional[List[StrictStr]] = Field(default=None, description="Tracks which rooms the server should be listed in; this will not be set when a room is listed to preserve privacy of servers.")
|
||||
auth_token: Optional[StrictStr] = Field(default=None, description="Used to authenticate requests which access knocks for this server or attempt to update, delete or create services. In future calls, add a header with the format: Authorization: Bearer <auth_token>", alias="authToken")
|
||||
display_name: Optional[StrictStr] = Field(default=None, alias="displayName")
|
||||
services: Optional[List[Service]] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "rooms", "authToken", "displayName", "services"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of Server from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in services (list)
|
||||
_items = []
|
||||
if self.services:
|
||||
for _item in self.services:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['services'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of Server from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"rooms": obj.get("rooms"),
|
||||
"authToken": obj.get("authToken"),
|
||||
"displayName": obj.get("displayName"),
|
||||
"services": [Service.from_dict(_item) for _item in obj["services"]] if obj.get("services") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
91
demo_server/demo_client/openapi_client/models/service.py
Normal file
91
demo_server/demo_client/openapi_client/models/service.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class Service(BaseModel):
|
||||
"""
|
||||
Service
|
||||
""" # noqa: E501
|
||||
name: Optional[StrictStr] = None
|
||||
protocol: Optional[StrictStr] = None
|
||||
version: Optional[StrictStr] = None
|
||||
__properties: ClassVar[List[str]] = ["name", "protocol", "version"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of Service from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of Service from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"name": obj.get("name"),
|
||||
"protocol": obj.get("protocol"),
|
||||
"version": obj.get("version")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
99
demo_server/demo_client/openapi_client/models/status.py
Normal file
99
demo_server/demo_client/openapi_client/models/status.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
|
||||
from typing import Any, ClassVar, Dict, List, Optional
|
||||
from openapi_client.models.google_protobuf_any import GoogleProtobufAny
|
||||
from typing import Optional, Set
|
||||
from typing_extensions import Self
|
||||
|
||||
class Status(BaseModel):
|
||||
"""
|
||||
The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).
|
||||
""" # noqa: E501
|
||||
code: Optional[StrictInt] = Field(default=None, description="The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].")
|
||||
message: Optional[StrictStr] = Field(default=None, description="A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.")
|
||||
details: Optional[List[GoogleProtobufAny]] = Field(default=None, description="A list of messages that carry the error details. There is a common set of message types for APIs to use.")
|
||||
__properties: ClassVar[List[str]] = ["code", "message", "details"]
|
||||
|
||||
model_config = ConfigDict(
|
||||
populate_by_name=True,
|
||||
validate_assignment=True,
|
||||
protected_namespaces=(),
|
||||
)
|
||||
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.model_dump(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||
"""Create an instance of Status from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Return the dictionary representation of the model using alias.
|
||||
|
||||
This has the following differences from calling pydantic's
|
||||
`self.model_dump(by_alias=True)`:
|
||||
|
||||
* `None` is only added to the output dict for nullable fields that
|
||||
were set at model initialization. Other fields with value `None`
|
||||
are ignored.
|
||||
"""
|
||||
excluded_fields: Set[str] = set([
|
||||
])
|
||||
|
||||
_dict = self.model_dump(
|
||||
by_alias=True,
|
||||
exclude=excluded_fields,
|
||||
exclude_none=True,
|
||||
)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in details (list)
|
||||
_items = []
|
||||
if self.details:
|
||||
for _item in self.details:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['details'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||
"""Create an instance of Status from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return cls.model_validate(obj)
|
||||
|
||||
_obj = cls.model_validate({
|
||||
"code": obj.get("code"),
|
||||
"message": obj.get("message"),
|
||||
"details": [GoogleProtobufAny.from_dict(_item) for _item in obj["details"]] if obj.get("details") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
0
demo_server/demo_client/openapi_client/py.typed
Normal file
0
demo_server/demo_client/openapi_client/py.typed
Normal file
255
demo_server/demo_client/openapi_client/rest.py
Normal file
255
demo_server/demo_client/openapi_client/rest.py
Normal file
@@ -0,0 +1,255 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import io
|
||||
import json
|
||||
import re
|
||||
import ssl
|
||||
|
||||
import urllib3
|
||||
|
||||
from openapi_client.exceptions import ApiException, ApiValueError
|
||||
|
||||
SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
|
||||
RESTResponseType = urllib3.HTTPResponse
|
||||
|
||||
|
||||
def is_socks_proxy_url(url):
|
||||
if url is None:
|
||||
return False
|
||||
split_section = url.split("://")
|
||||
if len(split_section) < 2:
|
||||
return False
|
||||
else:
|
||||
return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES
|
||||
|
||||
|
||||
class RESTResponse(io.IOBase):
|
||||
|
||||
def __init__(self, resp) -> None:
|
||||
self.response = resp
|
||||
self.status = resp.status
|
||||
self.reason = resp.reason
|
||||
self.data = None
|
||||
|
||||
def read(self):
|
||||
if self.data is None:
|
||||
self.data = self.response.data
|
||||
return self.data
|
||||
|
||||
def getheaders(self):
|
||||
"""Returns a dictionary of the response headers."""
|
||||
return self.response.headers
|
||||
|
||||
def getheader(self, name, default=None):
|
||||
"""Returns a given response header."""
|
||||
return self.response.headers.get(name, default)
|
||||
|
||||
|
||||
class RESTClientObject:
|
||||
|
||||
def __init__(self, configuration) -> None:
|
||||
# urllib3.PoolManager will pass all kw parameters to connectionpool
|
||||
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
|
||||
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
|
||||
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
|
||||
|
||||
# cert_reqs
|
||||
if configuration.verify_ssl:
|
||||
cert_reqs = ssl.CERT_REQUIRED
|
||||
else:
|
||||
cert_reqs = ssl.CERT_NONE
|
||||
|
||||
pool_args = {
|
||||
"cert_reqs": cert_reqs,
|
||||
"ca_certs": configuration.ssl_ca_cert,
|
||||
"cert_file": configuration.cert_file,
|
||||
"key_file": configuration.key_file,
|
||||
}
|
||||
if configuration.assert_hostname is not None:
|
||||
pool_args['assert_hostname'] = (
|
||||
configuration.assert_hostname
|
||||
)
|
||||
|
||||
if configuration.retries is not None:
|
||||
pool_args['retries'] = configuration.retries
|
||||
|
||||
if configuration.tls_server_name:
|
||||
pool_args['server_hostname'] = configuration.tls_server_name
|
||||
|
||||
|
||||
if configuration.socket_options is not None:
|
||||
pool_args['socket_options'] = configuration.socket_options
|
||||
|
||||
if configuration.connection_pool_maxsize is not None:
|
||||
pool_args['maxsize'] = configuration.connection_pool_maxsize
|
||||
|
||||
# https pool manager
|
||||
self.pool_manager: urllib3.PoolManager
|
||||
|
||||
if configuration.proxy:
|
||||
if is_socks_proxy_url(configuration.proxy):
|
||||
from urllib3.contrib.socks import SOCKSProxyManager
|
||||
pool_args["proxy_url"] = configuration.proxy
|
||||
pool_args["headers"] = configuration.proxy_headers
|
||||
self.pool_manager = SOCKSProxyManager(**pool_args)
|
||||
else:
|
||||
pool_args["proxy_url"] = configuration.proxy
|
||||
pool_args["proxy_headers"] = configuration.proxy_headers
|
||||
self.pool_manager = urllib3.ProxyManager(**pool_args)
|
||||
else:
|
||||
self.pool_manager = urllib3.PoolManager(**pool_args)
|
||||
|
||||
def request(
|
||||
self,
|
||||
method,
|
||||
url,
|
||||
headers=None,
|
||||
body=None,
|
||||
post_params=None,
|
||||
_request_timeout=None
|
||||
):
|
||||
"""Perform requests.
|
||||
|
||||
:param method: http request method
|
||||
:param url: http request url
|
||||
:param headers: http request headers
|
||||
:param body: request json body, for `application/json`
|
||||
:param post_params: request post parameters,
|
||||
`application/x-www-form-urlencoded`
|
||||
and `multipart/form-data`
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
"""
|
||||
method = method.upper()
|
||||
assert method in [
|
||||
'GET',
|
||||
'HEAD',
|
||||
'DELETE',
|
||||
'POST',
|
||||
'PUT',
|
||||
'PATCH',
|
||||
'OPTIONS'
|
||||
]
|
||||
|
||||
if post_params and body:
|
||||
raise ApiValueError(
|
||||
"body parameter cannot be used with post_params parameter."
|
||||
)
|
||||
|
||||
post_params = post_params or {}
|
||||
headers = headers or {}
|
||||
|
||||
timeout = None
|
||||
if _request_timeout:
|
||||
if isinstance(_request_timeout, (int, float)):
|
||||
timeout = urllib3.Timeout(total=_request_timeout)
|
||||
elif (
|
||||
isinstance(_request_timeout, tuple)
|
||||
and len(_request_timeout) == 2
|
||||
):
|
||||
timeout = urllib3.Timeout(
|
||||
connect=_request_timeout[0],
|
||||
read=_request_timeout[1]
|
||||
)
|
||||
|
||||
try:
|
||||
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
||||
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
|
||||
|
||||
# no content type provided or payload is json
|
||||
content_type = headers.get('Content-Type')
|
||||
if (
|
||||
not content_type
|
||||
or re.search('json', content_type, re.IGNORECASE)
|
||||
):
|
||||
request_body = None
|
||||
if body is not None:
|
||||
request_body = json.dumps(body)
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
body=request_body,
|
||||
timeout=timeout,
|
||||
headers=headers,
|
||||
preload_content=False
|
||||
)
|
||||
elif content_type == 'application/x-www-form-urlencoded':
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
fields=post_params,
|
||||
encode_multipart=False,
|
||||
timeout=timeout,
|
||||
headers=headers,
|
||||
preload_content=False
|
||||
)
|
||||
elif content_type == 'multipart/form-data':
|
||||
# must del headers['Content-Type'], or the correct
|
||||
# Content-Type which generated by urllib3 will be
|
||||
# overwritten.
|
||||
del headers['Content-Type']
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
fields=post_params,
|
||||
encode_multipart=True,
|
||||
timeout=timeout,
|
||||
headers=headers,
|
||||
preload_content=False
|
||||
)
|
||||
# Pass a `string` parameter directly in the body to support
|
||||
# other content types than JSON when `body` argument is
|
||||
# provided in serialized form.
|
||||
elif isinstance(body, str) or isinstance(body, bytes):
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
body=body,
|
||||
timeout=timeout,
|
||||
headers=headers,
|
||||
preload_content=False
|
||||
)
|
||||
elif headers['Content-Type'] == 'text/plain' and isinstance(body, bool):
|
||||
request_body = "true" if body else "false"
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
body=request_body,
|
||||
preload_content=False,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
else:
|
||||
# Cannot generate the request from given parameters
|
||||
msg = """Cannot prepare a request message for provided
|
||||
arguments. Please check that your arguments match
|
||||
declared content type."""
|
||||
raise ApiException(status=0, reason=msg)
|
||||
# For `GET`, `HEAD`
|
||||
else:
|
||||
r = self.pool_manager.request(
|
||||
method,
|
||||
url,
|
||||
fields={},
|
||||
timeout=timeout,
|
||||
headers=headers,
|
||||
preload_content=False
|
||||
)
|
||||
except urllib3.exceptions.SSLError as e:
|
||||
msg = "\n".join([type(e).__name__, str(e)])
|
||||
raise ApiException(status=0, reason=msg)
|
||||
|
||||
return RESTResponse(r)
|
||||
71
demo_server/demo_client/pyproject.toml
Normal file
71
demo_server/demo_client/pyproject.toml
Normal file
@@ -0,0 +1,71 @@
|
||||
[tool.poetry]
|
||||
name = "openapi_client"
|
||||
version = "1.0.0"
|
||||
description = "PeerNetService API"
|
||||
authors = ["OpenAPI Generator Community <team@openapitools.org>"]
|
||||
license = "NoLicense"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/GIT_USER_ID/GIT_REPO_ID"
|
||||
keywords = ["OpenAPI", "OpenAPI-Generator", "PeerNetService API"]
|
||||
include = ["openapi_client/py.typed"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
|
||||
urllib3 = ">= 1.25.3"
|
||||
python-dateutil = ">=2.8.2"
|
||||
pydantic = ">=2"
|
||||
typing-extensions = ">=4.7.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = ">=7.2.1"
|
||||
tox = ">=3.9.0"
|
||||
flake8 = ">=4.0.0"
|
||||
types-python-dateutil = ">=2.8.19.14"
|
||||
mypy = "1.4.1"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.pylint.'MESSAGES CONTROL']
|
||||
extension-pkg-whitelist = "pydantic"
|
||||
|
||||
[tool.mypy]
|
||||
files = [
|
||||
"openapi_client",
|
||||
#"test", # auto-generated tests
|
||||
"tests", # hand-written tests
|
||||
]
|
||||
# TODO: enable "strict" once all these individual checks are passing
|
||||
# strict = true
|
||||
|
||||
# List from: https://mypy.readthedocs.io/en/stable/existing_code.html#introduce-stricter-options
|
||||
warn_unused_configs = true
|
||||
warn_redundant_casts = true
|
||||
warn_unused_ignores = true
|
||||
|
||||
## Getting these passing should be easy
|
||||
strict_equality = true
|
||||
strict_concatenate = true
|
||||
|
||||
## Strongly recommend enabling this one as soon as you can
|
||||
check_untyped_defs = true
|
||||
|
||||
## These shouldn't be too much additional work, but may be tricky to
|
||||
## get passing if you use a lot of untyped libraries
|
||||
disallow_subclassing_any = true
|
||||
disallow_untyped_decorators = true
|
||||
disallow_any_generics = true
|
||||
|
||||
### These next few are various gradations of forcing use of type annotations
|
||||
#disallow_untyped_calls = true
|
||||
#disallow_incomplete_defs = true
|
||||
#disallow_untyped_defs = true
|
||||
#
|
||||
### This one isn't too hard to get passing, but return on investment is lower
|
||||
#no_implicit_reexport = true
|
||||
#
|
||||
### This one can be tricky to get passing if you use a lot of untyped libraries
|
||||
#warn_return_any = true
|
||||
5
demo_server/demo_client/requirements.txt
Normal file
5
demo_server/demo_client/requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
python_dateutil >= 2.5.3
|
||||
setuptools >= 21.0.0
|
||||
urllib3 >= 1.25.3, < 2.1.0
|
||||
pydantic >= 2
|
||||
typing-extensions >= 4.7.1
|
||||
2
demo_server/demo_client/setup.cfg
Normal file
2
demo_server/demo_client/setup.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[flake8]
|
||||
max-line-length=99
|
||||
49
demo_server/demo_client/setup.py
Normal file
49
demo_server/demo_client/setup.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from setuptools import setup, find_packages # noqa: H301
|
||||
|
||||
# To install the library, run the following
|
||||
#
|
||||
# python setup.py install
|
||||
#
|
||||
# prerequisite: setuptools
|
||||
# http://pypi.python.org/pypi/setuptools
|
||||
NAME = "openapi-client"
|
||||
VERSION = "1.0.0"
|
||||
PYTHON_REQUIRES = ">=3.7"
|
||||
REQUIRES = [
|
||||
"urllib3 >= 1.25.3, < 2.1.0",
|
||||
"python-dateutil",
|
||||
"pydantic >= 2",
|
||||
"typing-extensions >= 4.7.1",
|
||||
]
|
||||
|
||||
setup(
|
||||
name=NAME,
|
||||
version=VERSION,
|
||||
description="PeerNetService API",
|
||||
author="OpenAPI Generator community",
|
||||
author_email="team@openapitools.org",
|
||||
url="",
|
||||
keywords=["OpenAPI", "OpenAPI-Generator", "PeerNetService API"],
|
||||
install_requires=REQUIRES,
|
||||
packages=find_packages(exclude=["test", "tests"]),
|
||||
include_package_data=True,
|
||||
long_description_content_type='text/markdown',
|
||||
long_description="""\
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
""", # noqa: E501
|
||||
package_data={"openapi_client": ["py.typed"]},
|
||||
)
|
||||
5
demo_server/demo_client/test-requirements.txt
Normal file
5
demo_server/demo_client/test-requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
pytest~=7.1.3
|
||||
pytest-cov>=2.8.1
|
||||
pytest-randomly>=3.12.0
|
||||
mypy>=1.4.1
|
||||
types-python-dateutil>=2.8.19
|
||||
0
demo_server/demo_client/test/__init__.py
Normal file
0
demo_server/demo_client/test/__init__.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
|
||||
class TestClaimIceCandidatesResponse(unittest.TestCase):
|
||||
"""ClaimIceCandidatesResponse unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> ClaimIceCandidatesResponse:
|
||||
"""Test ClaimIceCandidatesResponse
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `ClaimIceCandidatesResponse`
|
||||
"""
|
||||
model = ClaimIceCandidatesResponse()
|
||||
if include_optional:
|
||||
return ClaimIceCandidatesResponse(
|
||||
ice_candidates = [
|
||||
openapi_client.models.ice_candidate.IceCandidate(
|
||||
name = '',
|
||||
candidate = '',
|
||||
sdp_mid = '',
|
||||
sdp_line_index = 56,
|
||||
username_fragment = '', )
|
||||
]
|
||||
)
|
||||
else:
|
||||
return ClaimIceCandidatesResponse(
|
||||
)
|
||||
"""
|
||||
|
||||
def testClaimIceCandidatesResponse(self):
|
||||
"""Test ClaimIceCandidatesResponse"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
51
demo_server/demo_client/test/test_google_protobuf_any.py
Normal file
51
demo_server/demo_client/test/test_google_protobuf_any.py
Normal file
@@ -0,0 +1,51 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.google_protobuf_any import GoogleProtobufAny
|
||||
|
||||
class TestGoogleProtobufAny(unittest.TestCase):
|
||||
"""GoogleProtobufAny unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> GoogleProtobufAny:
|
||||
"""Test GoogleProtobufAny
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `GoogleProtobufAny`
|
||||
"""
|
||||
model = GoogleProtobufAny()
|
||||
if include_optional:
|
||||
return GoogleProtobufAny(
|
||||
type = ''
|
||||
)
|
||||
else:
|
||||
return GoogleProtobufAny(
|
||||
)
|
||||
"""
|
||||
|
||||
def testGoogleProtobufAny(self):
|
||||
"""Test GoogleProtobufAny"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
55
demo_server/demo_client/test/test_ice_candidate.py
Normal file
55
demo_server/demo_client/test/test_ice_candidate.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.ice_candidate import IceCandidate
|
||||
|
||||
class TestIceCandidate(unittest.TestCase):
|
||||
"""IceCandidate unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> IceCandidate:
|
||||
"""Test IceCandidate
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `IceCandidate`
|
||||
"""
|
||||
model = IceCandidate()
|
||||
if include_optional:
|
||||
return IceCandidate(
|
||||
name = '',
|
||||
candidate = '',
|
||||
sdp_mid = '',
|
||||
sdp_line_index = 56,
|
||||
username_fragment = ''
|
||||
)
|
||||
else:
|
||||
return IceCandidate(
|
||||
)
|
||||
"""
|
||||
|
||||
def testIceCandidate(self):
|
||||
"""Test IceCandidate"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
53
demo_server/demo_client/test/test_ice_session_description.py
Normal file
53
demo_server/demo_client/test/test_ice_session_description.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.ice_session_description import IceSessionDescription
|
||||
|
||||
class TestIceSessionDescription(unittest.TestCase):
|
||||
"""IceSessionDescription unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> IceSessionDescription:
|
||||
"""Test IceSessionDescription
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `IceSessionDescription`
|
||||
"""
|
||||
model = IceSessionDescription()
|
||||
if include_optional:
|
||||
return IceSessionDescription(
|
||||
name = '',
|
||||
sdp_type = '',
|
||||
sdp = ''
|
||||
)
|
||||
else:
|
||||
return IceSessionDescription(
|
||||
)
|
||||
"""
|
||||
|
||||
def testIceSessionDescription(self):
|
||||
"""Test IceSessionDescription"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
63
demo_server/demo_client/test/test_knock.py
Normal file
63
demo_server/demo_client/test/test_knock.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.knock import Knock
|
||||
|
||||
class TestKnock(unittest.TestCase):
|
||||
"""Knock unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> Knock:
|
||||
"""Test Knock
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `Knock`
|
||||
"""
|
||||
model = Knock()
|
||||
if include_optional:
|
||||
return Knock(
|
||||
name = '',
|
||||
service = openapi_client.models.service.Service(
|
||||
name = '',
|
||||
protocol = '',
|
||||
version = '', ),
|
||||
offer = openapi_client.models.ice_session_description.IceSessionDescription(
|
||||
name = '',
|
||||
sdp_type = '',
|
||||
sdp = '', ),
|
||||
answer = openapi_client.models.ice_session_description.IceSessionDescription(
|
||||
name = '',
|
||||
sdp_type = '',
|
||||
sdp = '', )
|
||||
)
|
||||
else:
|
||||
return Knock(
|
||||
)
|
||||
"""
|
||||
|
||||
def testKnock(self):
|
||||
"""Test Knock"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
63
demo_server/demo_client/test/test_list_knocks_response.py
Normal file
63
demo_server/demo_client/test/test_list_knocks_response.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.list_knocks_response import ListKnocksResponse
|
||||
|
||||
class TestListKnocksResponse(unittest.TestCase):
|
||||
"""ListKnocksResponse unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> ListKnocksResponse:
|
||||
"""Test ListKnocksResponse
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `ListKnocksResponse`
|
||||
"""
|
||||
model = ListKnocksResponse()
|
||||
if include_optional:
|
||||
return ListKnocksResponse(
|
||||
knocks = [
|
||||
openapi_client.models.knock.Knock(
|
||||
name = '',
|
||||
service = null,
|
||||
offer = openapi_client.models.ice_session_description.IceSessionDescription(
|
||||
name = '',
|
||||
sdp_type = '',
|
||||
sdp = '', ),
|
||||
answer = openapi_client.models.ice_session_description.IceSessionDescription(
|
||||
name = '',
|
||||
sdp_type = '',
|
||||
sdp = '', ), )
|
||||
]
|
||||
)
|
||||
else:
|
||||
return ListKnocksResponse(
|
||||
)
|
||||
"""
|
||||
|
||||
def testListKnocksResponse(self):
|
||||
"""Test ListKnocksResponse"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
91
demo_server/demo_client/test/test_peer_net_service_api.py
Normal file
91
demo_server/demo_client/test/test_peer_net_service_api.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.api.peer_net_service_api import PeerNetServiceApi
|
||||
|
||||
|
||||
class TestPeerNetServiceApi(unittest.TestCase):
|
||||
"""PeerNetServiceApi unit test stubs"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.api = PeerNetServiceApi()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
pass
|
||||
|
||||
def test_peer_net_service_claim_ice_candidates(self) -> None:
|
||||
"""Test case for peer_net_service_claim_ice_candidates
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_create_ice_candidate(self) -> None:
|
||||
"""Test case for peer_net_service_create_ice_candidate
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_create_knock(self) -> None:
|
||||
"""Test case for peer_net_service_create_knock
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_create_server(self) -> None:
|
||||
"""Test case for peer_net_service_create_server
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_create_service(self) -> None:
|
||||
"""Test case for peer_net_service_create_service
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_delete_server(self) -> None:
|
||||
"""Test case for peer_net_service_delete_server
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_delete_service(self) -> None:
|
||||
"""Test case for peer_net_service_delete_service
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_get_room(self) -> None:
|
||||
"""Test case for peer_net_service_get_room
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_list_knocks(self) -> None:
|
||||
"""Test case for peer_net_service_list_knocks
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def test_peer_net_service_update_knock(self) -> None:
|
||||
"""Test case for peer_net_service_update_knock
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
67
demo_server/demo_client/test/test_room.py
Normal file
67
demo_server/demo_client/test/test_room.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.room import Room
|
||||
|
||||
class TestRoom(unittest.TestCase):
|
||||
"""Room unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> Room:
|
||||
"""Test Room
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `Room`
|
||||
"""
|
||||
model = Room()
|
||||
if include_optional:
|
||||
return Room(
|
||||
name = '',
|
||||
display_name = '',
|
||||
servers = [
|
||||
openapi_client.models.server.Server(
|
||||
name = '',
|
||||
rooms = [
|
||||
''
|
||||
],
|
||||
auth_token = '',
|
||||
display_name = '',
|
||||
services = [
|
||||
openapi_client.models.service.Service(
|
||||
name = '',
|
||||
protocol = '',
|
||||
version = '', )
|
||||
], )
|
||||
]
|
||||
)
|
||||
else:
|
||||
return Room(
|
||||
)
|
||||
"""
|
||||
|
||||
def testRoom(self):
|
||||
"""Test Room"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
62
demo_server/demo_client/test/test_server.py
Normal file
62
demo_server/demo_client/test/test_server.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.server import Server
|
||||
|
||||
class TestServer(unittest.TestCase):
|
||||
"""Server unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> Server:
|
||||
"""Test Server
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `Server`
|
||||
"""
|
||||
model = Server()
|
||||
if include_optional:
|
||||
return Server(
|
||||
name = '',
|
||||
rooms = [
|
||||
''
|
||||
],
|
||||
auth_token = '',
|
||||
display_name = '',
|
||||
services = [
|
||||
openapi_client.models.service.Service(
|
||||
name = '',
|
||||
protocol = '',
|
||||
version = '', )
|
||||
]
|
||||
)
|
||||
else:
|
||||
return Server(
|
||||
)
|
||||
"""
|
||||
|
||||
def testServer(self):
|
||||
"""Test Server"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
53
demo_server/demo_client/test/test_service.py
Normal file
53
demo_server/demo_client/test/test_service.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.service import Service
|
||||
|
||||
class TestService(unittest.TestCase):
|
||||
"""Service unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> Service:
|
||||
"""Test Service
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `Service`
|
||||
"""
|
||||
model = Service()
|
||||
if include_optional:
|
||||
return Service(
|
||||
name = '',
|
||||
protocol = '',
|
||||
version = ''
|
||||
)
|
||||
else:
|
||||
return Service(
|
||||
)
|
||||
"""
|
||||
|
||||
def testService(self):
|
||||
"""Test Service"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
55
demo_server/demo_client/test/test_status.py
Normal file
55
demo_server/demo_client/test/test_status.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
PeerNetService API
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.0.1
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
from openapi_client.models.status import Status
|
||||
|
||||
class TestStatus(unittest.TestCase):
|
||||
"""Status unit test stubs"""
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def make_instance(self, include_optional) -> Status:
|
||||
"""Test Status
|
||||
include_option is a boolean, when False only required
|
||||
params are included, when True both required and
|
||||
optional params are included """
|
||||
# uncomment below to create an instance of `Status`
|
||||
"""
|
||||
model = Status()
|
||||
if include_optional:
|
||||
return Status(
|
||||
code = 56,
|
||||
message = '',
|
||||
details = [
|
||||
{ }
|
||||
]
|
||||
)
|
||||
else:
|
||||
return Status(
|
||||
)
|
||||
"""
|
||||
|
||||
def testStatus(self):
|
||||
"""Test Status"""
|
||||
# inst_req_only = self.make_instance(include_optional=False)
|
||||
# inst_req_and_optional = self.make_instance(include_optional=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
9
demo_server/demo_client/tox.ini
Normal file
9
demo_server/demo_client/tox.ini
Normal file
@@ -0,0 +1,9 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
|
||||
[testenv]
|
||||
deps=-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
|
||||
commands=
|
||||
pytest --cov=openapi_client
|
||||
57
demo_server/git_push.sh
Normal file
57
demo_server/git_push.sh
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||
#
|
||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
git_host=$4
|
||||
|
||||
if [ "$git_host" = "" ]; then
|
||||
git_host="github.com"
|
||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
||||
fi
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="GIT_USER_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="GIT_REPO_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="Minor update"
|
||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||
fi
|
||||
|
||||
# Initialize the local directory as a Git repository
|
||||
git init
|
||||
|
||||
# Adds the files in the local repository and stages them for commit.
|
||||
git add .
|
||||
|
||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||
git commit -m "$release_note"
|
||||
|
||||
# Sets the new remote
|
||||
git_remote=$(git remote)
|
||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||
|
||||
if [ "$GIT_TOKEN" = "" ]; then
|
||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
git pull origin master
|
||||
|
||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
0
demo_server/openapi_server/__init__.py
Normal file
0
demo_server/openapi_server/__init__.py
Normal file
19
demo_server/openapi_server/__main__.py
Normal file
19
demo_server/openapi_server/__main__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import connexion
|
||||
|
||||
from openapi_server import encoder
|
||||
|
||||
|
||||
def main():
|
||||
app = connexion.App(__name__, specification_dir='./openapi/')
|
||||
app.app.json_encoder = encoder.JSONEncoder
|
||||
app.add_api('openapi.yaml',
|
||||
arguments={'title': 'PeerNetService API'},
|
||||
pythonic_params=True)
|
||||
|
||||
app.run(port=8080)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
0
demo_server/openapi_server/controllers/__init__.py
Normal file
0
demo_server/openapi_server/controllers/__init__.py
Normal file
@@ -0,0 +1,227 @@
|
||||
import connexion
|
||||
from typing import Dict
|
||||
from typing import Tuple
|
||||
from typing import Union
|
||||
|
||||
from openapi_server.models.claim_ice_candidates_response import ClaimIceCandidatesResponse # noqa: E501
|
||||
from openapi_server.models.ice_candidate import IceCandidate # noqa: E501
|
||||
from openapi_server.models.knock import Knock # noqa: E501
|
||||
from openapi_server.models.list_knocks_response import ListKnocksResponse # noqa: E501
|
||||
from openapi_server.models.room import Room # noqa: E501
|
||||
from openapi_server.models.server import Server # noqa: E501
|
||||
from openapi_server.models.service import Service # noqa: E501
|
||||
from openapi_server.models.status import Status # noqa: E501
|
||||
from openapi_server import util
|
||||
|
||||
servers = {}
|
||||
rooms = {}
|
||||
knocks = {}
|
||||
sessions = {}
|
||||
|
||||
def peer_net_service_claim_ice_candidates(session): # noqa: E501
|
||||
"""peer_net_service_claim_ice_candidates
|
||||
|
||||
Acts as both List and Delete atomically. # noqa: E501
|
||||
|
||||
:param session: The session id.
|
||||
:type session: str
|
||||
:param name:
|
||||
:type name: str
|
||||
|
||||
:rtype: Union[ClaimIceCandidatesResponse, Tuple[ClaimIceCandidatesResponse, int], Tuple[ClaimIceCandidatesResponse, int, Dict[str, str]]
|
||||
"""
|
||||
if session not in sessions:
|
||||
return 'not found', 404
|
||||
candidates = [sessions[session][k] for k in sessions[session]]
|
||||
sessions[session] = {}
|
||||
return ClaimIceCandidatesResponse(ice_candidates=candidates)
|
||||
|
||||
|
||||
def peer_net_service_create_ice_candidate(session, ice_candidate=None, target_session=None): # noqa: E501
|
||||
"""peer_net_service_create_ice_candidate
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param session: The session id.
|
||||
:type session: str
|
||||
:param ice_candidate:
|
||||
:type ice_candidate: dict | bytes
|
||||
:param target_session:
|
||||
:type target_session: str
|
||||
|
||||
:rtype: Union[IceCandidate, Tuple[IceCandidate, int], Tuple[IceCandidate, int, Dict[str, str]]
|
||||
"""
|
||||
if connexion.request.is_json:
|
||||
ice_candidate = IceCandidate.from_dict(connexion.request.get_json()) # noqa: E501
|
||||
sessions[session][ice_candidate.name] = ice_candidate
|
||||
return ice_candidate
|
||||
|
||||
|
||||
def peer_net_service_create_knock(server, service, knock=None): # noqa: E501
|
||||
"""peer_net_service_create_knock
|
||||
|
||||
Creates a knock that will be answered by the peer; the signaler may delete the knock, regardless of the state, when it ages. # noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service: The service id.
|
||||
:type service: str
|
||||
:param knock:
|
||||
:type knock: dict | bytes
|
||||
|
||||
:rtype: Union[Knock, Tuple[Knock, int], Tuple[Knock, int, Dict[str, str]]
|
||||
"""
|
||||
if connexion.request.is_json:
|
||||
knock = Knock.from_dict(connexion.request.get_json()) # noqa: E501
|
||||
print(knock)
|
||||
if server not in servers or service not in [s.name for s in servers[server].services]:
|
||||
return 'not found', 404
|
||||
knocks[server][service][knock.name] = knock
|
||||
sessions[knock.offer.name] = {}
|
||||
return knock
|
||||
|
||||
|
||||
def peer_net_service_create_server(server=None): # noqa: E501
|
||||
"""peer_net_service_create_server
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server:
|
||||
:type server: dict | bytes
|
||||
|
||||
:rtype: Union[Server, Tuple[Server, int], Tuple[Server, int, Dict[str, str]]
|
||||
"""
|
||||
if connexion.request.is_json:
|
||||
server = Server.from_dict(connexion.request.get_json()) # noqa: E501
|
||||
servers[server.name] = server
|
||||
for room in server.rooms:
|
||||
if room not in rooms:
|
||||
rooms[room] = {}
|
||||
rooms[room][server.name] = server
|
||||
knocks[server.name] = {}
|
||||
for service in server.services:
|
||||
knocks[server.name][service.name] = {}
|
||||
return server
|
||||
|
||||
|
||||
def peer_net_service_create_service(server, service): # noqa: E501
|
||||
"""peer_net_service_create_service
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service:
|
||||
:type service: dict | bytes
|
||||
|
||||
:rtype: Union[Service, Tuple[Service, int], Tuple[Service, int, Dict[str, str]]
|
||||
"""
|
||||
if connexion.request.is_json:
|
||||
service = Service.from_dict(connexion.request.get_json()) # noqa: E501
|
||||
return 'do some magic!'
|
||||
|
||||
|
||||
def peer_net_service_delete_server(name=None): # noqa: E501
|
||||
"""peer_net_service_delete_server
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param name:
|
||||
:type name: str
|
||||
|
||||
:rtype: Union[None, Tuple[None, int], Tuple[None, int, Dict[str, str]]
|
||||
"""
|
||||
return 'do some magic!'
|
||||
|
||||
|
||||
def peer_net_service_delete_service(server, service): # noqa: E501
|
||||
"""peer_net_service_delete_service
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service: The service id.
|
||||
:type service: str
|
||||
|
||||
:rtype: Union[None, Tuple[None, int], Tuple[None, int, Dict[str, str]]
|
||||
"""
|
||||
return 'do some magic!'
|
||||
|
||||
|
||||
def peer_net_service_get_knock(server, service, knock): # noqa: E501
|
||||
"""peer_net_service_get_knock
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service: The service id.
|
||||
:type service: str
|
||||
:param knock: The knock id.
|
||||
:type knock: str
|
||||
|
||||
:rtype: Union[Knock, Tuple[Knock, int], Tuple[Knock, int, Dict[str, str]]
|
||||
"""
|
||||
if server not in knocks or service not in knocks[server] or knock not in knocks[server][service]:
|
||||
return 'not found', 404
|
||||
return knocks[server][service][knock]
|
||||
|
||||
def peer_net_service_get_room(room): # noqa: E501
|
||||
"""peer_net_service_get_room
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param room: The room id.
|
||||
:type room: str
|
||||
|
||||
:rtype: Union[Room, Tuple[Room, int], Tuple[Room, int, Dict[str, str]]
|
||||
"""
|
||||
if room not in rooms:
|
||||
return 'not found', 404
|
||||
s = []
|
||||
for server in rooms[room]:
|
||||
s.append(servers[server])
|
||||
return Room(name=room, servers=s)
|
||||
|
||||
|
||||
def peer_net_service_list_knocks(server, service): # noqa: E501
|
||||
"""peer_net_service_list_knocks
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service: The service id.
|
||||
:type service: str
|
||||
|
||||
:rtype: Union[ListKnocksResponse, Tuple[ListKnocksResponse, int], Tuple[ListKnocksResponse, int, Dict[str, str]]
|
||||
"""
|
||||
if server not in knocks or service not in knocks[server]:
|
||||
return 'not found', 404
|
||||
return ListKnocksResponse(knocks=[knocks[server][service][k] for k in knocks[server][service]])
|
||||
|
||||
|
||||
def peer_net_service_update_knock(server, service, knock, knock2=None): # noqa: E501
|
||||
"""peer_net_service_update_knock
|
||||
|
||||
# noqa: E501
|
||||
|
||||
:param server: The server id.
|
||||
:type server: str
|
||||
:param service: The service id.
|
||||
:type service: str
|
||||
:param knock: The knock id.
|
||||
:type knock: str
|
||||
:param knock2:
|
||||
:type knock2: dict | bytes
|
||||
|
||||
:rtype: Union[Knock, Tuple[Knock, int], Tuple[Knock, int, Dict[str, str]]
|
||||
"""
|
||||
if connexion.request.is_json:
|
||||
knock2 = Knock.from_dict(connexion.request.get_json()) # noqa: E501
|
||||
if server not in servers or service not in [s.name for s in servers[server].services]:
|
||||
return 'not found', 404
|
||||
knocks[server][service][knock] = knock2
|
||||
sessions[knock2.answer.name] = {}
|
||||
return knock2
|
||||
@@ -0,0 +1,2 @@
|
||||
from typing import List
|
||||
|
||||
19
demo_server/openapi_server/encoder.py
Normal file
19
demo_server/openapi_server/encoder.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from connexion.apps.flask_app import FlaskJSONEncoder
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
|
||||
|
||||
class JSONEncoder(FlaskJSONEncoder):
|
||||
include_nulls = False
|
||||
|
||||
def default(self, o):
|
||||
if isinstance(o, Model):
|
||||
dikt = {}
|
||||
for attr in o.openapi_types:
|
||||
value = getattr(o, attr)
|
||||
if value is None and not self.include_nulls:
|
||||
continue
|
||||
attr = o.attribute_map[attr]
|
||||
dikt[attr] = value
|
||||
return dikt
|
||||
return FlaskJSONEncoder.default(self, o)
|
||||
12
demo_server/openapi_server/models/__init__.py
Normal file
12
demo_server/openapi_server/models/__init__.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# flake8: noqa
|
||||
# import models into model package
|
||||
from openapi_server.models.claim_ice_candidates_response import ClaimIceCandidatesResponse
|
||||
from openapi_server.models.google_protobuf_any import GoogleProtobufAny
|
||||
from openapi_server.models.ice_candidate import IceCandidate
|
||||
from openapi_server.models.ice_session_description import IceSessionDescription
|
||||
from openapi_server.models.knock import Knock
|
||||
from openapi_server.models.list_knocks_response import ListKnocksResponse
|
||||
from openapi_server.models.room import Room
|
||||
from openapi_server.models.server import Server
|
||||
from openapi_server.models.service import Service
|
||||
from openapi_server.models.status import Status
|
||||
68
demo_server/openapi_server/models/base_model.py
Normal file
68
demo_server/openapi_server/models/base_model.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import pprint
|
||||
|
||||
import typing
|
||||
|
||||
from openapi_server import util
|
||||
|
||||
T = typing.TypeVar('T')
|
||||
|
||||
|
||||
class Model:
|
||||
# openapiTypes: The key is attribute name and the
|
||||
# value is attribute type.
|
||||
openapi_types: typing.Dict[str, type] = {}
|
||||
|
||||
# attributeMap: The key is attribute name and the
|
||||
# value is json key in definition.
|
||||
attribute_map: typing.Dict[str, str] = {}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls: typing.Type[T], dikt) -> T:
|
||||
"""Returns the dict as a model"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the model properties as a dict
|
||||
|
||||
:rtype: dict
|
||||
"""
|
||||
result = {}
|
||||
|
||||
for attr in self.openapi_types:
|
||||
value = getattr(self, attr)
|
||||
if isinstance(value, list):
|
||||
result[attr] = list(map(
|
||||
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
||||
value
|
||||
))
|
||||
elif hasattr(value, "to_dict"):
|
||||
result[attr] = value.to_dict()
|
||||
elif isinstance(value, dict):
|
||||
result[attr] = dict(map(
|
||||
lambda item: (item[0], item[1].to_dict())
|
||||
if hasattr(item[1], "to_dict") else item,
|
||||
value.items()
|
||||
))
|
||||
else:
|
||||
result[attr] = value
|
||||
|
||||
return result
|
||||
|
||||
def to_str(self):
|
||||
"""Returns the string representation of the model
|
||||
|
||||
:rtype: str
|
||||
"""
|
||||
return pprint.pformat(self.to_dict())
|
||||
|
||||
def __repr__(self):
|
||||
"""For `print` and `pprint`"""
|
||||
return self.to_str()
|
||||
|
||||
def __eq__(self, other):
|
||||
"""Returns true if both objects are equal"""
|
||||
return self.__dict__ == other.__dict__
|
||||
|
||||
def __ne__(self, other):
|
||||
"""Returns true if both objects are not equal"""
|
||||
return not self == other
|
||||
@@ -0,0 +1,63 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.ice_candidate import IceCandidate
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.ice_candidate import IceCandidate # noqa: E501
|
||||
|
||||
class ClaimIceCandidatesResponse(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, ice_candidates=None): # noqa: E501
|
||||
"""ClaimIceCandidatesResponse - a model defined in OpenAPI
|
||||
|
||||
:param ice_candidates: The ice_candidates of this ClaimIceCandidatesResponse. # noqa: E501
|
||||
:type ice_candidates: List[IceCandidate]
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'ice_candidates': List[IceCandidate]
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'ice_candidates': 'iceCandidates'
|
||||
}
|
||||
|
||||
self._ice_candidates = ice_candidates
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'ClaimIceCandidatesResponse':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The ClaimIceCandidatesResponse of this ClaimIceCandidatesResponse. # noqa: E501
|
||||
:rtype: ClaimIceCandidatesResponse
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def ice_candidates(self) -> List[IceCandidate]:
|
||||
"""Gets the ice_candidates of this ClaimIceCandidatesResponse.
|
||||
|
||||
|
||||
:return: The ice_candidates of this ClaimIceCandidatesResponse.
|
||||
:rtype: List[IceCandidate]
|
||||
"""
|
||||
return self._ice_candidates
|
||||
|
||||
@ice_candidates.setter
|
||||
def ice_candidates(self, ice_candidates: List[IceCandidate]):
|
||||
"""Sets the ice_candidates of this ClaimIceCandidatesResponse.
|
||||
|
||||
|
||||
:param ice_candidates: The ice_candidates of this ClaimIceCandidatesResponse.
|
||||
:type ice_candidates: List[IceCandidate]
|
||||
"""
|
||||
|
||||
self._ice_candidates = ice_candidates
|
||||
63
demo_server/openapi_server/models/google_protobuf_any.py
Normal file
63
demo_server/openapi_server/models/google_protobuf_any.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server import util
|
||||
|
||||
|
||||
class GoogleProtobufAny(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, type=None): # noqa: E501
|
||||
"""GoogleProtobufAny - a model defined in OpenAPI
|
||||
|
||||
:param type: The type of this GoogleProtobufAny. # noqa: E501
|
||||
:type type: str
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'type': str
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'type': '@type'
|
||||
}
|
||||
|
||||
self._type = type
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'GoogleProtobufAny':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The GoogleProtobufAny of this GoogleProtobufAny. # noqa: E501
|
||||
:rtype: GoogleProtobufAny
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
"""Gets the type of this GoogleProtobufAny.
|
||||
|
||||
The type of the serialized message. # noqa: E501
|
||||
|
||||
:return: The type of this GoogleProtobufAny.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, type: str):
|
||||
"""Sets the type of this GoogleProtobufAny.
|
||||
|
||||
The type of the serialized message. # noqa: E501
|
||||
|
||||
:param type: The type of this GoogleProtobufAny.
|
||||
:type type: str
|
||||
"""
|
||||
|
||||
self._type = type
|
||||
165
demo_server/openapi_server/models/ice_candidate.py
Normal file
165
demo_server/openapi_server/models/ice_candidate.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server import util
|
||||
|
||||
|
||||
class IceCandidate(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, candidate=None, sdp_mid=None, sdp_line_index=None, username_fragment=None): # noqa: E501
|
||||
"""IceCandidate - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this IceCandidate. # noqa: E501
|
||||
:type name: str
|
||||
:param candidate: The candidate of this IceCandidate. # noqa: E501
|
||||
:type candidate: str
|
||||
:param sdp_mid: The sdp_mid of this IceCandidate. # noqa: E501
|
||||
:type sdp_mid: str
|
||||
:param sdp_line_index: The sdp_line_index of this IceCandidate. # noqa: E501
|
||||
:type sdp_line_index: int
|
||||
:param username_fragment: The username_fragment of this IceCandidate. # noqa: E501
|
||||
:type username_fragment: str
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'candidate': str,
|
||||
'sdp_mid': str,
|
||||
'sdp_line_index': int,
|
||||
'username_fragment': str
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'candidate': 'candidate',
|
||||
'sdp_mid': 'sdpMid',
|
||||
'sdp_line_index': 'sdpLineIndex',
|
||||
'username_fragment': 'usernameFragment'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._candidate = candidate
|
||||
self._sdp_mid = sdp_mid
|
||||
self._sdp_line_index = sdp_line_index
|
||||
self._username_fragment = username_fragment
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'IceCandidate':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The IceCandidate of this IceCandidate. # noqa: E501
|
||||
:rtype: IceCandidate
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this IceCandidate.
|
||||
|
||||
|
||||
:return: The name of this IceCandidate.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this IceCandidate.
|
||||
|
||||
|
||||
:param name: The name of this IceCandidate.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def candidate(self) -> str:
|
||||
"""Gets the candidate of this IceCandidate.
|
||||
|
||||
|
||||
:return: The candidate of this IceCandidate.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._candidate
|
||||
|
||||
@candidate.setter
|
||||
def candidate(self, candidate: str):
|
||||
"""Sets the candidate of this IceCandidate.
|
||||
|
||||
|
||||
:param candidate: The candidate of this IceCandidate.
|
||||
:type candidate: str
|
||||
"""
|
||||
|
||||
self._candidate = candidate
|
||||
|
||||
@property
|
||||
def sdp_mid(self) -> str:
|
||||
"""Gets the sdp_mid of this IceCandidate.
|
||||
|
||||
|
||||
:return: The sdp_mid of this IceCandidate.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._sdp_mid
|
||||
|
||||
@sdp_mid.setter
|
||||
def sdp_mid(self, sdp_mid: str):
|
||||
"""Sets the sdp_mid of this IceCandidate.
|
||||
|
||||
|
||||
:param sdp_mid: The sdp_mid of this IceCandidate.
|
||||
:type sdp_mid: str
|
||||
"""
|
||||
|
||||
self._sdp_mid = sdp_mid
|
||||
|
||||
@property
|
||||
def sdp_line_index(self) -> int:
|
||||
"""Gets the sdp_line_index of this IceCandidate.
|
||||
|
||||
|
||||
:return: The sdp_line_index of this IceCandidate.
|
||||
:rtype: int
|
||||
"""
|
||||
return self._sdp_line_index
|
||||
|
||||
@sdp_line_index.setter
|
||||
def sdp_line_index(self, sdp_line_index: int):
|
||||
"""Sets the sdp_line_index of this IceCandidate.
|
||||
|
||||
|
||||
:param sdp_line_index: The sdp_line_index of this IceCandidate.
|
||||
:type sdp_line_index: int
|
||||
"""
|
||||
|
||||
self._sdp_line_index = sdp_line_index
|
||||
|
||||
@property
|
||||
def username_fragment(self) -> str:
|
||||
"""Gets the username_fragment of this IceCandidate.
|
||||
|
||||
|
||||
:return: The username_fragment of this IceCandidate.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._username_fragment
|
||||
|
||||
@username_fragment.setter
|
||||
def username_fragment(self, username_fragment: str):
|
||||
"""Sets the username_fragment of this IceCandidate.
|
||||
|
||||
|
||||
:param username_fragment: The username_fragment of this IceCandidate.
|
||||
:type username_fragment: str
|
||||
"""
|
||||
|
||||
self._username_fragment = username_fragment
|
||||
117
demo_server/openapi_server/models/ice_session_description.py
Normal file
117
demo_server/openapi_server/models/ice_session_description.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server import util
|
||||
|
||||
|
||||
class IceSessionDescription(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, sdp_type=None, sdp=None): # noqa: E501
|
||||
"""IceSessionDescription - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this IceSessionDescription. # noqa: E501
|
||||
:type name: str
|
||||
:param sdp_type: The sdp_type of this IceSessionDescription. # noqa: E501
|
||||
:type sdp_type: str
|
||||
:param sdp: The sdp of this IceSessionDescription. # noqa: E501
|
||||
:type sdp: str
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'sdp_type': str,
|
||||
'sdp': str
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'sdp_type': 'sdpType',
|
||||
'sdp': 'sdp'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._sdp_type = sdp_type
|
||||
self._sdp = sdp
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'IceSessionDescription':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The IceSessionDescription of this IceSessionDescription. # noqa: E501
|
||||
:rtype: IceSessionDescription
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this IceSessionDescription.
|
||||
|
||||
A unique identifier which can be used to send ICE candidates Maps to the session name # noqa: E501
|
||||
|
||||
:return: The name of this IceSessionDescription.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this IceSessionDescription.
|
||||
|
||||
A unique identifier which can be used to send ICE candidates Maps to the session name # noqa: E501
|
||||
|
||||
:param name: The name of this IceSessionDescription.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def sdp_type(self) -> str:
|
||||
"""Gets the sdp_type of this IceSessionDescription.
|
||||
|
||||
Used to construct the remote description in WebRTC # noqa: E501
|
||||
|
||||
:return: The sdp_type of this IceSessionDescription.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._sdp_type
|
||||
|
||||
@sdp_type.setter
|
||||
def sdp_type(self, sdp_type: str):
|
||||
"""Sets the sdp_type of this IceSessionDescription.
|
||||
|
||||
Used to construct the remote description in WebRTC # noqa: E501
|
||||
|
||||
:param sdp_type: The sdp_type of this IceSessionDescription.
|
||||
:type sdp_type: str
|
||||
"""
|
||||
|
||||
self._sdp_type = sdp_type
|
||||
|
||||
@property
|
||||
def sdp(self) -> str:
|
||||
"""Gets the sdp of this IceSessionDescription.
|
||||
|
||||
|
||||
:return: The sdp of this IceSessionDescription.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._sdp
|
||||
|
||||
@sdp.setter
|
||||
def sdp(self, sdp: str):
|
||||
"""Sets the sdp of this IceSessionDescription.
|
||||
|
||||
|
||||
:param sdp: The sdp of this IceSessionDescription.
|
||||
:type sdp: str
|
||||
"""
|
||||
|
||||
self._sdp = sdp
|
||||
117
demo_server/openapi_server/models/knock.py
Normal file
117
demo_server/openapi_server/models/knock.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.ice_session_description import IceSessionDescription
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.ice_session_description import IceSessionDescription # noqa: E501
|
||||
|
||||
class Knock(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, offer=None, answer=None): # noqa: E501
|
||||
"""Knock - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this Knock. # noqa: E501
|
||||
:type name: str
|
||||
:param offer: The offer of this Knock. # noqa: E501
|
||||
:type offer: IceSessionDescription
|
||||
:param answer: The answer of this Knock. # noqa: E501
|
||||
:type answer: IceSessionDescription
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'offer': IceSessionDescription,
|
||||
'answer': IceSessionDescription
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'offer': 'offer',
|
||||
'answer': 'answer'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._offer = offer
|
||||
self._answer = answer
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'Knock':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The Knock of this Knock. # noqa: E501
|
||||
:rtype: Knock
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this Knock.
|
||||
|
||||
|
||||
:return: The name of this Knock.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this Knock.
|
||||
|
||||
|
||||
:param name: The name of this Knock.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def offer(self) -> IceSessionDescription:
|
||||
"""Gets the offer of this Knock.
|
||||
|
||||
The service being connected too # noqa: E501
|
||||
|
||||
:return: The offer of this Knock.
|
||||
:rtype: IceSessionDescription
|
||||
"""
|
||||
return self._offer
|
||||
|
||||
@offer.setter
|
||||
def offer(self, offer: IceSessionDescription):
|
||||
"""Sets the offer of this Knock.
|
||||
|
||||
The service being connected too # noqa: E501
|
||||
|
||||
:param offer: The offer of this Knock.
|
||||
:type offer: IceSessionDescription
|
||||
"""
|
||||
|
||||
self._offer = offer
|
||||
|
||||
@property
|
||||
def answer(self) -> IceSessionDescription:
|
||||
"""Gets the answer of this Knock.
|
||||
|
||||
|
||||
:return: The answer of this Knock.
|
||||
:rtype: IceSessionDescription
|
||||
"""
|
||||
return self._answer
|
||||
|
||||
@answer.setter
|
||||
def answer(self, answer: IceSessionDescription):
|
||||
"""Sets the answer of this Knock.
|
||||
|
||||
|
||||
:param answer: The answer of this Knock.
|
||||
:type answer: IceSessionDescription
|
||||
"""
|
||||
|
||||
self._answer = answer
|
||||
63
demo_server/openapi_server/models/list_knocks_response.py
Normal file
63
demo_server/openapi_server/models/list_knocks_response.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.knock import Knock
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.knock import Knock # noqa: E501
|
||||
|
||||
class ListKnocksResponse(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, knocks=None): # noqa: E501
|
||||
"""ListKnocksResponse - a model defined in OpenAPI
|
||||
|
||||
:param knocks: The knocks of this ListKnocksResponse. # noqa: E501
|
||||
:type knocks: List[Knock]
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'knocks': List[Knock]
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'knocks': 'knocks'
|
||||
}
|
||||
|
||||
self._knocks = knocks
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'ListKnocksResponse':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The ListKnocksResponse of this ListKnocksResponse. # noqa: E501
|
||||
:rtype: ListKnocksResponse
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def knocks(self) -> List[Knock]:
|
||||
"""Gets the knocks of this ListKnocksResponse.
|
||||
|
||||
|
||||
:return: The knocks of this ListKnocksResponse.
|
||||
:rtype: List[Knock]
|
||||
"""
|
||||
return self._knocks
|
||||
|
||||
@knocks.setter
|
||||
def knocks(self, knocks: List[Knock]):
|
||||
"""Sets the knocks of this ListKnocksResponse.
|
||||
|
||||
|
||||
:param knocks: The knocks of this ListKnocksResponse.
|
||||
:type knocks: List[Knock]
|
||||
"""
|
||||
|
||||
self._knocks = knocks
|
||||
115
demo_server/openapi_server/models/room.py
Normal file
115
demo_server/openapi_server/models/room.py
Normal file
@@ -0,0 +1,115 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.server import Server
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.server import Server # noqa: E501
|
||||
|
||||
class Room(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, display_name=None, servers=None): # noqa: E501
|
||||
"""Room - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this Room. # noqa: E501
|
||||
:type name: str
|
||||
:param display_name: The display_name of this Room. # noqa: E501
|
||||
:type display_name: str
|
||||
:param servers: The servers of this Room. # noqa: E501
|
||||
:type servers: List[Server]
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'display_name': str,
|
||||
'servers': List[Server]
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'display_name': 'displayName',
|
||||
'servers': 'servers'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._display_name = display_name
|
||||
self._servers = servers
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'Room':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The Room of this Room. # noqa: E501
|
||||
:rtype: Room
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this Room.
|
||||
|
||||
|
||||
:return: The name of this Room.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this Room.
|
||||
|
||||
|
||||
:param name: The name of this Room.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
"""Gets the display_name of this Room.
|
||||
|
||||
|
||||
:return: The display_name of this Room.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._display_name
|
||||
|
||||
@display_name.setter
|
||||
def display_name(self, display_name: str):
|
||||
"""Sets the display_name of this Room.
|
||||
|
||||
|
||||
:param display_name: The display_name of this Room.
|
||||
:type display_name: str
|
||||
"""
|
||||
|
||||
self._display_name = display_name
|
||||
|
||||
@property
|
||||
def servers(self) -> List[Server]:
|
||||
"""Gets the servers of this Room.
|
||||
|
||||
|
||||
:return: The servers of this Room.
|
||||
:rtype: List[Server]
|
||||
"""
|
||||
return self._servers
|
||||
|
||||
@servers.setter
|
||||
def servers(self, servers: List[Server]):
|
||||
"""Sets the servers of this Room.
|
||||
|
||||
|
||||
:param servers: The servers of this Room.
|
||||
:type servers: List[Server]
|
||||
"""
|
||||
|
||||
self._servers = servers
|
||||
171
demo_server/openapi_server/models/server.py
Normal file
171
demo_server/openapi_server/models/server.py
Normal file
@@ -0,0 +1,171 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.service import Service
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.service import Service # noqa: E501
|
||||
|
||||
class Server(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, rooms=None, auth_token=None, display_name=None, services=None): # noqa: E501
|
||||
"""Server - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this Server. # noqa: E501
|
||||
:type name: str
|
||||
:param rooms: The rooms of this Server. # noqa: E501
|
||||
:type rooms: List[str]
|
||||
:param auth_token: The auth_token of this Server. # noqa: E501
|
||||
:type auth_token: str
|
||||
:param display_name: The display_name of this Server. # noqa: E501
|
||||
:type display_name: str
|
||||
:param services: The services of this Server. # noqa: E501
|
||||
:type services: List[Service]
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'rooms': List[str],
|
||||
'auth_token': str,
|
||||
'display_name': str,
|
||||
'services': List[Service]
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'rooms': 'rooms',
|
||||
'auth_token': 'authToken',
|
||||
'display_name': 'displayName',
|
||||
'services': 'services'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._rooms = rooms
|
||||
self._auth_token = auth_token
|
||||
self._display_name = display_name
|
||||
self._services = services
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'Server':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The Server of this Server. # noqa: E501
|
||||
:rtype: Server
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this Server.
|
||||
|
||||
|
||||
:return: The name of this Server.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this Server.
|
||||
|
||||
|
||||
:param name: The name of this Server.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def rooms(self) -> List[str]:
|
||||
"""Gets the rooms of this Server.
|
||||
|
||||
Tracks which rooms the server should be listed in; this will not be set when a room is listed to preserve privacy of servers. # noqa: E501
|
||||
|
||||
:return: The rooms of this Server.
|
||||
:rtype: List[str]
|
||||
"""
|
||||
return self._rooms
|
||||
|
||||
@rooms.setter
|
||||
def rooms(self, rooms: List[str]):
|
||||
"""Sets the rooms of this Server.
|
||||
|
||||
Tracks which rooms the server should be listed in; this will not be set when a room is listed to preserve privacy of servers. # noqa: E501
|
||||
|
||||
:param rooms: The rooms of this Server.
|
||||
:type rooms: List[str]
|
||||
"""
|
||||
|
||||
self._rooms = rooms
|
||||
|
||||
@property
|
||||
def auth_token(self) -> str:
|
||||
"""Gets the auth_token of this Server.
|
||||
|
||||
Used to authenticate requests which access knocks for this server or attempt to update, delete or create services. In future calls, add a header with the format: Authorization: Bearer <auth_token> # noqa: E501
|
||||
|
||||
:return: The auth_token of this Server.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._auth_token
|
||||
|
||||
@auth_token.setter
|
||||
def auth_token(self, auth_token: str):
|
||||
"""Sets the auth_token of this Server.
|
||||
|
||||
Used to authenticate requests which access knocks for this server or attempt to update, delete or create services. In future calls, add a header with the format: Authorization: Bearer <auth_token> # noqa: E501
|
||||
|
||||
:param auth_token: The auth_token of this Server.
|
||||
:type auth_token: str
|
||||
"""
|
||||
|
||||
self._auth_token = auth_token
|
||||
|
||||
@property
|
||||
def display_name(self) -> str:
|
||||
"""Gets the display_name of this Server.
|
||||
|
||||
|
||||
:return: The display_name of this Server.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._display_name
|
||||
|
||||
@display_name.setter
|
||||
def display_name(self, display_name: str):
|
||||
"""Sets the display_name of this Server.
|
||||
|
||||
|
||||
:param display_name: The display_name of this Server.
|
||||
:type display_name: str
|
||||
"""
|
||||
|
||||
self._display_name = display_name
|
||||
|
||||
@property
|
||||
def services(self) -> List[Service]:
|
||||
"""Gets the services of this Server.
|
||||
|
||||
|
||||
:return: The services of this Server.
|
||||
:rtype: List[Service]
|
||||
"""
|
||||
return self._services
|
||||
|
||||
@services.setter
|
||||
def services(self, services: List[Service]):
|
||||
"""Sets the services of this Server.
|
||||
|
||||
|
||||
:param services: The services of this Server.
|
||||
:type services: List[Service]
|
||||
"""
|
||||
|
||||
self._services = services
|
||||
113
demo_server/openapi_server/models/service.py
Normal file
113
demo_server/openapi_server/models/service.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server import util
|
||||
|
||||
|
||||
class Service(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, protocol=None, version=None): # noqa: E501
|
||||
"""Service - a model defined in OpenAPI
|
||||
|
||||
:param name: The name of this Service. # noqa: E501
|
||||
:type name: str
|
||||
:param protocol: The protocol of this Service. # noqa: E501
|
||||
:type protocol: str
|
||||
:param version: The version of this Service. # noqa: E501
|
||||
:type version: str
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'name': str,
|
||||
'protocol': str,
|
||||
'version': str
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'name': 'name',
|
||||
'protocol': 'protocol',
|
||||
'version': 'version'
|
||||
}
|
||||
|
||||
self._name = name
|
||||
self._protocol = protocol
|
||||
self._version = version
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'Service':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The Service of this Service. # noqa: E501
|
||||
:rtype: Service
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Gets the name of this Service.
|
||||
|
||||
|
||||
:return: The name of this Service.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, name: str):
|
||||
"""Sets the name of this Service.
|
||||
|
||||
|
||||
:param name: The name of this Service.
|
||||
:type name: str
|
||||
"""
|
||||
|
||||
self._name = name
|
||||
|
||||
@property
|
||||
def protocol(self) -> str:
|
||||
"""Gets the protocol of this Service.
|
||||
|
||||
|
||||
:return: The protocol of this Service.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._protocol
|
||||
|
||||
@protocol.setter
|
||||
def protocol(self, protocol: str):
|
||||
"""Sets the protocol of this Service.
|
||||
|
||||
|
||||
:param protocol: The protocol of this Service.
|
||||
:type protocol: str
|
||||
"""
|
||||
|
||||
self._protocol = protocol
|
||||
|
||||
@property
|
||||
def version(self) -> str:
|
||||
"""Gets the version of this Service.
|
||||
|
||||
|
||||
:return: The version of this Service.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._version
|
||||
|
||||
@version.setter
|
||||
def version(self, version: str):
|
||||
"""Sets the version of this Service.
|
||||
|
||||
|
||||
:param version: The version of this Service.
|
||||
:type version: str
|
||||
"""
|
||||
|
||||
self._version = version
|
||||
121
demo_server/openapi_server/models/status.py
Normal file
121
demo_server/openapi_server/models/status.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from datetime import date, datetime # noqa: F401
|
||||
|
||||
from typing import List, Dict # noqa: F401
|
||||
|
||||
from openapi_server.models.base_model import Model
|
||||
from openapi_server.models.google_protobuf_any import GoogleProtobufAny
|
||||
from openapi_server import util
|
||||
|
||||
from openapi_server.models.google_protobuf_any import GoogleProtobufAny # noqa: E501
|
||||
|
||||
class Status(Model):
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, code=None, message=None, details=None): # noqa: E501
|
||||
"""Status - a model defined in OpenAPI
|
||||
|
||||
:param code: The code of this Status. # noqa: E501
|
||||
:type code: int
|
||||
:param message: The message of this Status. # noqa: E501
|
||||
:type message: str
|
||||
:param details: The details of this Status. # noqa: E501
|
||||
:type details: List[GoogleProtobufAny]
|
||||
"""
|
||||
self.openapi_types = {
|
||||
'code': int,
|
||||
'message': str,
|
||||
'details': List[GoogleProtobufAny]
|
||||
}
|
||||
|
||||
self.attribute_map = {
|
||||
'code': 'code',
|
||||
'message': 'message',
|
||||
'details': 'details'
|
||||
}
|
||||
|
||||
self._code = code
|
||||
self._message = message
|
||||
self._details = details
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, dikt) -> 'Status':
|
||||
"""Returns the dict as a model
|
||||
|
||||
:param dikt: A dict.
|
||||
:type: dict
|
||||
:return: The Status of this Status. # noqa: E501
|
||||
:rtype: Status
|
||||
"""
|
||||
return util.deserialize_model(dikt, cls)
|
||||
|
||||
@property
|
||||
def code(self) -> int:
|
||||
"""Gets the code of this Status.
|
||||
|
||||
The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. # noqa: E501
|
||||
|
||||
:return: The code of this Status.
|
||||
:rtype: int
|
||||
"""
|
||||
return self._code
|
||||
|
||||
@code.setter
|
||||
def code(self, code: int):
|
||||
"""Sets the code of this Status.
|
||||
|
||||
The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. # noqa: E501
|
||||
|
||||
:param code: The code of this Status.
|
||||
:type code: int
|
||||
"""
|
||||
|
||||
self._code = code
|
||||
|
||||
@property
|
||||
def message(self) -> str:
|
||||
"""Gets the message of this Status.
|
||||
|
||||
A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. # noqa: E501
|
||||
|
||||
:return: The message of this Status.
|
||||
:rtype: str
|
||||
"""
|
||||
return self._message
|
||||
|
||||
@message.setter
|
||||
def message(self, message: str):
|
||||
"""Sets the message of this Status.
|
||||
|
||||
A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. # noqa: E501
|
||||
|
||||
:param message: The message of this Status.
|
||||
:type message: str
|
||||
"""
|
||||
|
||||
self._message = message
|
||||
|
||||
@property
|
||||
def details(self) -> List[GoogleProtobufAny]:
|
||||
"""Gets the details of this Status.
|
||||
|
||||
A list of messages that carry the error details. There is a common set of message types for APIs to use. # noqa: E501
|
||||
|
||||
:return: The details of this Status.
|
||||
:rtype: List[GoogleProtobufAny]
|
||||
"""
|
||||
return self._details
|
||||
|
||||
@details.setter
|
||||
def details(self, details: List[GoogleProtobufAny]):
|
||||
"""Sets the details of this Status.
|
||||
|
||||
A list of messages that carry the error details. There is a common set of message types for APIs to use. # noqa: E501
|
||||
|
||||
:param details: The details of this Status.
|
||||
:type details: List[GoogleProtobufAny]
|
||||
"""
|
||||
|
||||
self._details = details
|
||||
658
demo_server/openapi_server/openapi/openapi.yaml
Normal file
658
demo_server/openapi_server/openapi/openapi.yaml
Normal file
@@ -0,0 +1,658 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: PeerNetService API
|
||||
version: 0.0.1
|
||||
servers:
|
||||
- url: /
|
||||
tags:
|
||||
- name: PeerNetService
|
||||
paths:
|
||||
/v1/rooms/{room}:
|
||||
get:
|
||||
operationId: peer_net_service_get_room
|
||||
parameters:
|
||||
- description: The room id.
|
||||
explode: false
|
||||
in: path
|
||||
name: room
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Room'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers:
|
||||
post:
|
||||
operationId: peer_net_service_create_server
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Server'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Server'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers/*:
|
||||
delete:
|
||||
operationId: peer_net_service_delete_server
|
||||
parameters:
|
||||
- explode: true
|
||||
in: query
|
||||
name: name
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
style: form
|
||||
responses:
|
||||
"200":
|
||||
content: {}
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers/{server}/services:
|
||||
post:
|
||||
operationId: peer_net_service_create_service
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Service'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Service'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers/{server}/services/{service}:
|
||||
delete:
|
||||
operationId: peer_net_service_delete_service
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The service id.
|
||||
explode: false
|
||||
in: path
|
||||
name: service
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content: {}
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers/{server}/services/{service}/knocks:
|
||||
get:
|
||||
operationId: peer_net_service_list_knocks
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The service id.
|
||||
explode: false
|
||||
in: path
|
||||
name: service
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListKnocksResponse'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
post:
|
||||
description: |-
|
||||
Creates a knock that will be answered by the peer; the signaler may
|
||||
delete the knock, regardless of the state, when it ages.
|
||||
operationId: peer_net_service_create_knock
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The service id.
|
||||
explode: false
|
||||
in: path
|
||||
name: service
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/servers/{server}/services/{service}/knocks/{knock}:
|
||||
get:
|
||||
operationId: peer_net_service_get_knock
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The service id.
|
||||
explode: false
|
||||
in: path
|
||||
name: service
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The knock id.
|
||||
explode: false
|
||||
in: path
|
||||
name: knock
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
patch:
|
||||
operationId: peer_net_service_update_knock
|
||||
parameters:
|
||||
- description: The server id.
|
||||
explode: false
|
||||
in: path
|
||||
name: server
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The service id.
|
||||
explode: false
|
||||
in: path
|
||||
name: service
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
- description: The knock id.
|
||||
explode: false
|
||||
in: path
|
||||
name: knock
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/sessions/{session}/candidates:
|
||||
post:
|
||||
operationId: peer_net_service_create_ice_candidate
|
||||
parameters:
|
||||
- description: The session id.
|
||||
explode: false
|
||||
in: path
|
||||
name: session
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IceCandidate'
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IceCandidate'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
/v1/sessions/{session}/claim/candidates:
|
||||
get:
|
||||
description: Acts as both List and Delete atomically.
|
||||
operationId: peer_net_service_claim_ice_candidates
|
||||
parameters:
|
||||
- description: The session id.
|
||||
explode: false
|
||||
in: path
|
||||
name: session
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ClaimIceCandidatesResponse'
|
||||
description: OK
|
||||
default:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Status'
|
||||
description: Default error response
|
||||
tags:
|
||||
- PeerNetService
|
||||
x-openapi-router-controller: openapi_server.controllers.peer_net_service_controller
|
||||
components:
|
||||
schemas:
|
||||
ClaimIceCandidatesResponse:
|
||||
example:
|
||||
iceCandidates:
|
||||
- candidate: candidate
|
||||
usernameFragment: usernameFragment
|
||||
name: name
|
||||
sdpMid: sdpMid
|
||||
sdpLineIndex: 0
|
||||
- candidate: candidate
|
||||
usernameFragment: usernameFragment
|
||||
name: name
|
||||
sdpMid: sdpMid
|
||||
sdpLineIndex: 0
|
||||
properties:
|
||||
iceCandidates:
|
||||
items:
|
||||
$ref: '#/components/schemas/IceCandidate'
|
||||
title: iceCandidates
|
||||
type: array
|
||||
title: ClaimIceCandidatesResponse
|
||||
type: object
|
||||
GoogleProtobufAny:
|
||||
additionalProperties: true
|
||||
description: Contains an arbitrary serialized message along with a @type that
|
||||
describes the type of the serialized message.
|
||||
example:
|
||||
'@type': '@type'
|
||||
properties:
|
||||
'@type':
|
||||
description: The type of the serialized message.
|
||||
type: string
|
||||
title: GoogleProtobufAny
|
||||
type: object
|
||||
IceCandidate:
|
||||
example:
|
||||
candidate: candidate
|
||||
usernameFragment: usernameFragment
|
||||
name: name
|
||||
sdpMid: sdpMid
|
||||
sdpLineIndex: 0
|
||||
properties:
|
||||
name:
|
||||
title: name
|
||||
type: string
|
||||
candidate:
|
||||
title: candidate
|
||||
type: string
|
||||
sdpMid:
|
||||
title: sdpMid
|
||||
type: string
|
||||
sdpLineIndex:
|
||||
format: int32
|
||||
title: sdpLineIndex
|
||||
type: integer
|
||||
usernameFragment:
|
||||
title: usernameFragment
|
||||
type: string
|
||||
title: IceCandidate
|
||||
type: object
|
||||
IceSessionDescription:
|
||||
example:
|
||||
name: name
|
||||
sdpType: sdpType
|
||||
sdp: sdp
|
||||
properties:
|
||||
name:
|
||||
description: |-
|
||||
A unique identifier which can be used to send ICE candidates
|
||||
Maps to the session name
|
||||
title: name
|
||||
type: string
|
||||
sdpType:
|
||||
description: Used to construct the remote description in WebRTC
|
||||
title: sdpType
|
||||
type: string
|
||||
sdp:
|
||||
title: sdp
|
||||
type: string
|
||||
title: IceSessionDescription
|
||||
type: object
|
||||
Knock:
|
||||
example:
|
||||
offer: ""
|
||||
answer:
|
||||
name: name
|
||||
sdpType: sdpType
|
||||
sdp: sdp
|
||||
name: name
|
||||
properties:
|
||||
name:
|
||||
title: name
|
||||
type: string
|
||||
offer:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/IceSessionDescription'
|
||||
description: The service being connected too
|
||||
title: offer
|
||||
answer:
|
||||
$ref: '#/components/schemas/IceSessionDescription'
|
||||
title: Knock
|
||||
type: object
|
||||
ListKnocksResponse:
|
||||
example:
|
||||
knocks:
|
||||
- offer: ""
|
||||
answer:
|
||||
name: name
|
||||
sdpType: sdpType
|
||||
sdp: sdp
|
||||
name: name
|
||||
- offer: ""
|
||||
answer:
|
||||
name: name
|
||||
sdpType: sdpType
|
||||
sdp: sdp
|
||||
name: name
|
||||
properties:
|
||||
knocks:
|
||||
items:
|
||||
$ref: '#/components/schemas/Knock'
|
||||
title: knocks
|
||||
type: array
|
||||
title: ListKnocksResponse
|
||||
type: object
|
||||
Room:
|
||||
example:
|
||||
servers:
|
||||
- rooms:
|
||||
- rooms
|
||||
- rooms
|
||||
displayName: displayName
|
||||
authToken: authToken
|
||||
name: name
|
||||
services:
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
- rooms:
|
||||
- rooms
|
||||
- rooms
|
||||
displayName: displayName
|
||||
authToken: authToken
|
||||
name: name
|
||||
services:
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
displayName: displayName
|
||||
name: name
|
||||
properties:
|
||||
name:
|
||||
title: name
|
||||
type: string
|
||||
displayName:
|
||||
title: displayName
|
||||
type: string
|
||||
servers:
|
||||
items:
|
||||
$ref: '#/components/schemas/Server'
|
||||
title: servers
|
||||
type: array
|
||||
title: Room
|
||||
type: object
|
||||
Server:
|
||||
example:
|
||||
rooms:
|
||||
- rooms
|
||||
- rooms
|
||||
displayName: displayName
|
||||
authToken: authToken
|
||||
name: name
|
||||
services:
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
- protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
properties:
|
||||
name:
|
||||
title: name
|
||||
type: string
|
||||
rooms:
|
||||
description: |-
|
||||
Tracks which rooms the server should be listed in; this will not
|
||||
be set when a room is listed to preserve privacy of servers.
|
||||
items:
|
||||
type: string
|
||||
title: rooms
|
||||
type: array
|
||||
writeOnly: true
|
||||
authToken:
|
||||
description: |-
|
||||
Used to authenticate requests which access knocks for this server
|
||||
or attempt to update, delete or create services.
|
||||
In future calls, add a header with the format:
|
||||
Authorization: Bearer <auth_token>
|
||||
title: authToken
|
||||
type: string
|
||||
writeOnly: true
|
||||
displayName:
|
||||
title: displayName
|
||||
type: string
|
||||
services:
|
||||
items:
|
||||
$ref: '#/components/schemas/Service'
|
||||
title: services
|
||||
type: array
|
||||
title: Server
|
||||
type: object
|
||||
Service:
|
||||
example:
|
||||
protocol: protocol
|
||||
name: name
|
||||
version: version
|
||||
properties:
|
||||
name:
|
||||
title: name
|
||||
type: string
|
||||
protocol:
|
||||
title: protocol
|
||||
type: string
|
||||
version:
|
||||
title: version
|
||||
type: string
|
||||
title: Service
|
||||
type: object
|
||||
Status:
|
||||
description: "The `Status` type defines a logical error model that is suitable\
|
||||
\ for different programming environments, including REST APIs and RPC APIs.\
|
||||
\ It is used by [gRPC](https://github.com/grpc). Each `Status` message contains\
|
||||
\ three pieces of data: error code, error message, and error details. You\
|
||||
\ can find out more about this error model and how to work with it in the\
|
||||
\ [API Design Guide](https://cloud.google.com/apis/design/errors)."
|
||||
example:
|
||||
code: 0
|
||||
details:
|
||||
- '@type': '@type'
|
||||
- '@type': '@type'
|
||||
message: message
|
||||
properties:
|
||||
code:
|
||||
description: "The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]."
|
||||
format: int32
|
||||
title: code
|
||||
type: integer
|
||||
message:
|
||||
description: "A developer-facing error message, which should be in English.\
|
||||
\ Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details]\
|
||||
\ field, or localized by the client."
|
||||
title: message
|
||||
type: string
|
||||
details:
|
||||
description: A list of messages that carry the error details. There is
|
||||
a common set of message types for APIs to use.
|
||||
items:
|
||||
$ref: '#/components/schemas/GoogleProtobufAny'
|
||||
title: details
|
||||
type: array
|
||||
title: Status
|
||||
type: object
|
||||
16
demo_server/openapi_server/test/__init__.py
Normal file
16
demo_server/openapi_server/test/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import logging
|
||||
|
||||
import connexion
|
||||
from flask_testing import TestCase
|
||||
|
||||
from openapi_server.encoder import JSONEncoder
|
||||
|
||||
|
||||
class BaseTestCase(TestCase):
|
||||
|
||||
def create_app(self):
|
||||
logging.getLogger('connexion.operation').setLevel('ERROR')
|
||||
app = connexion.App(__name__, specification_dir='../openapi/')
|
||||
app.app.json_encoder = JSONEncoder
|
||||
app.add_api('openapi.yaml', pythonic_params=True)
|
||||
return app.app
|
||||
@@ -0,0 +1,200 @@
|
||||
import unittest
|
||||
|
||||
from flask import json
|
||||
|
||||
from openapi_server.models.claim_ice_candidates_response import ClaimIceCandidatesResponse # noqa: E501
|
||||
from openapi_server.models.ice_candidate import IceCandidate # noqa: E501
|
||||
from openapi_server.models.knock import Knock # noqa: E501
|
||||
from openapi_server.models.list_knocks_response import ListKnocksResponse # noqa: E501
|
||||
from openapi_server.models.room import Room # noqa: E501
|
||||
from openapi_server.models.server import Server # noqa: E501
|
||||
from openapi_server.models.service import Service # noqa: E501
|
||||
from openapi_server.models.status import Status # noqa: E501
|
||||
from openapi_server.test import BaseTestCase
|
||||
|
||||
|
||||
class TestPeerNetServiceController(BaseTestCase):
|
||||
"""PeerNetServiceController integration test stubs"""
|
||||
|
||||
def test_peer_net_service_claim_ice_candidates(self):
|
||||
"""Test case for peer_net_service_claim_ice_candidates
|
||||
|
||||
|
||||
"""
|
||||
query_string = [('name', 'name_example')]
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/sessions/{session}/claim/candidates'.format(session='session_example'),
|
||||
method='GET',
|
||||
headers=headers,
|
||||
query_string=query_string)
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_create_ice_candidate(self):
|
||||
"""Test case for peer_net_service_create_ice_candidate
|
||||
|
||||
|
||||
"""
|
||||
ice_candidate = {"candidate":"candidate","usernameFragment":"usernameFragment","sdpMid":"sdpMid","sdpLineIndex":0}
|
||||
query_string = [('targetSession', 'target_session_example')]
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/sessions/{session}/candidates'.format(session='session_example'),
|
||||
method='POST',
|
||||
headers=headers,
|
||||
data=json.dumps(ice_candidate),
|
||||
content_type='application/json',
|
||||
query_string=query_string)
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_create_knock(self):
|
||||
"""Test case for peer_net_service_create_knock
|
||||
|
||||
|
||||
"""
|
||||
knock = {"offer":{"name":"name","sdpType":"sdpType","sdp":"sdp"},"answer":{"name":"name","sdpType":"sdpType","sdp":"sdp"},"service":"","name":"name"}
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/{server}/sevices/{sevice}/knocks'.format(server='server_example', sevice='sevice_example'),
|
||||
method='POST',
|
||||
headers=headers,
|
||||
data=json.dumps(knock),
|
||||
content_type='application/json')
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_create_server(self):
|
||||
"""Test case for peer_net_service_create_server
|
||||
|
||||
|
||||
"""
|
||||
server = {"rooms":["rooms","rooms"],"displayName":"displayName","authToken":"authToken","name":"name","services":[{"protocol":"protocol","name":"name","version":"version"},{"protocol":"protocol","name":"name","version":"version"}]}
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers',
|
||||
method='POST',
|
||||
headers=headers,
|
||||
data=json.dumps(server),
|
||||
content_type='application/json')
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_create_service(self):
|
||||
"""Test case for peer_net_service_create_service
|
||||
|
||||
|
||||
"""
|
||||
return
|
||||
service = {"protocol":"protocol","name":"name","version":"version"}
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/{server}/services'.format(server='server_example'),
|
||||
method='POST',
|
||||
headers=headers,
|
||||
data=json.dumps(service),
|
||||
content_type='application/json')
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_delete_server(self):
|
||||
"""Test case for peer_net_service_delete_server
|
||||
|
||||
|
||||
"""
|
||||
query_string = [('name', 'name_example')]
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/*',
|
||||
method='DELETE',
|
||||
headers=headers,
|
||||
query_string=query_string)
|
||||
self.assert404(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_delete_service(self):
|
||||
"""Test case for peer_net_service_delete_service
|
||||
|
||||
|
||||
"""
|
||||
return
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/{server}/services/{service}'.format(server='server_example', service='service_example'),
|
||||
method='DELETE',
|
||||
headers=headers)
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_get_room(self):
|
||||
"""Test case for peer_net_service_get_room
|
||||
|
||||
|
||||
"""
|
||||
return
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/rooms/{room}'.format(room='room_example'),
|
||||
method='GET',
|
||||
headers=headers)
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_list_knocks(self):
|
||||
"""Test case for peer_net_service_list_knocks
|
||||
|
||||
|
||||
"""
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/{server}/services/{service}/knocks'.format(server='server_example', service='service_example'),
|
||||
method='GET',
|
||||
headers=headers)
|
||||
self.assert401(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
def test_peer_net_service_update_knock(self):
|
||||
"""Test case for peer_net_service_update_knock
|
||||
|
||||
|
||||
"""
|
||||
knock2 = {"offer":{"name":"name","sdpType":"sdpType","sdp":"sdp"},"answer":{"name":"name","sdpType":"sdpType","sdp":"sdp"},"service":"","name":"name"}
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
response = self.client.open(
|
||||
'/v1/servers/{server}/services/{service}/knocks/{knock}'.format(server='server_example', service='service_example', knock='knock_example'),
|
||||
method='PATCH',
|
||||
headers=headers,
|
||||
data=json.dumps(knock2),
|
||||
content_type='application/json')
|
||||
self.assert200(response,
|
||||
'Response body is : ' + response.data.decode('utf-8'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
30
demo_server/openapi_server/typing_utils.py
Normal file
30
demo_server/openapi_server/typing_utils.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 7):
|
||||
import typing
|
||||
|
||||
def is_generic(klass):
|
||||
""" Determine whether klass is a generic class """
|
||||
return type(klass) == typing.GenericMeta
|
||||
|
||||
def is_dict(klass):
|
||||
""" Determine whether klass is a Dict """
|
||||
return klass.__extra__ == dict
|
||||
|
||||
def is_list(klass):
|
||||
""" Determine whether klass is a List """
|
||||
return klass.__extra__ == list
|
||||
|
||||
else:
|
||||
|
||||
def is_generic(klass):
|
||||
""" Determine whether klass is a generic class """
|
||||
return hasattr(klass, '__origin__')
|
||||
|
||||
def is_dict(klass):
|
||||
""" Determine whether klass is a Dict """
|
||||
return klass.__origin__ == dict
|
||||
|
||||
def is_list(klass):
|
||||
""" Determine whether klass is a List """
|
||||
return klass.__origin__ == list
|
||||
147
demo_server/openapi_server/util.py
Normal file
147
demo_server/openapi_server/util.py
Normal file
@@ -0,0 +1,147 @@
|
||||
import datetime
|
||||
|
||||
import typing
|
||||
from openapi_server import typing_utils
|
||||
|
||||
|
||||
def _deserialize(data, klass):
|
||||
"""Deserializes dict, list, str into an object.
|
||||
|
||||
:param data: dict, list or str.
|
||||
:param klass: class literal, or string of class name.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if klass in (int, float, str, bool, bytearray):
|
||||
return _deserialize_primitive(data, klass)
|
||||
elif klass == object:
|
||||
return _deserialize_object(data)
|
||||
elif klass == datetime.date:
|
||||
return deserialize_date(data)
|
||||
elif klass == datetime.datetime:
|
||||
return deserialize_datetime(data)
|
||||
elif typing_utils.is_generic(klass):
|
||||
if typing_utils.is_list(klass):
|
||||
return _deserialize_list(data, klass.__args__[0])
|
||||
if typing_utils.is_dict(klass):
|
||||
return _deserialize_dict(data, klass.__args__[1])
|
||||
else:
|
||||
return deserialize_model(data, klass)
|
||||
|
||||
|
||||
def _deserialize_primitive(data, klass):
|
||||
"""Deserializes to primitive type.
|
||||
|
||||
:param data: data to deserialize.
|
||||
:param klass: class literal.
|
||||
|
||||
:return: int, long, float, str, bool.
|
||||
:rtype: int | long | float | str | bool
|
||||
"""
|
||||
try:
|
||||
value = klass(data)
|
||||
except UnicodeEncodeError:
|
||||
value = data
|
||||
except TypeError:
|
||||
value = data
|
||||
return value
|
||||
|
||||
|
||||
def _deserialize_object(value):
|
||||
"""Return an original value.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
return value
|
||||
|
||||
|
||||
def deserialize_date(string):
|
||||
"""Deserializes string to date.
|
||||
|
||||
:param string: str.
|
||||
:type string: str
|
||||
:return: date.
|
||||
:rtype: date
|
||||
"""
|
||||
if string is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
from dateutil.parser import parse
|
||||
return parse(string).date()
|
||||
except ImportError:
|
||||
return string
|
||||
|
||||
|
||||
def deserialize_datetime(string):
|
||||
"""Deserializes string to datetime.
|
||||
|
||||
The string should be in iso8601 datetime format.
|
||||
|
||||
:param string: str.
|
||||
:type string: str
|
||||
:return: datetime.
|
||||
:rtype: datetime
|
||||
"""
|
||||
if string is None:
|
||||
return None
|
||||
|
||||
try:
|
||||
from dateutil.parser import parse
|
||||
return parse(string)
|
||||
except ImportError:
|
||||
return string
|
||||
|
||||
|
||||
def deserialize_model(data, klass):
|
||||
"""Deserializes list or dict to model.
|
||||
|
||||
:param data: dict, list.
|
||||
:type data: dict | list
|
||||
:param klass: class literal.
|
||||
:return: model object.
|
||||
"""
|
||||
instance = klass()
|
||||
|
||||
if not instance.openapi_types:
|
||||
return data
|
||||
|
||||
for attr, attr_type in instance.openapi_types.items():
|
||||
if data is not None \
|
||||
and instance.attribute_map[attr] in data \
|
||||
and isinstance(data, (list, dict)):
|
||||
value = data[instance.attribute_map[attr]]
|
||||
setattr(instance, attr, _deserialize(value, attr_type))
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
def _deserialize_list(data, boxed_type):
|
||||
"""Deserializes a list and its elements.
|
||||
|
||||
:param data: list to deserialize.
|
||||
:type data: list
|
||||
:param boxed_type: class literal.
|
||||
|
||||
:return: deserialized list.
|
||||
:rtype: list
|
||||
"""
|
||||
return [_deserialize(sub_data, boxed_type)
|
||||
for sub_data in data]
|
||||
|
||||
|
||||
def _deserialize_dict(data, boxed_type):
|
||||
"""Deserializes a dict and its elements.
|
||||
|
||||
:param data: dict to deserialize.
|
||||
:type data: dict
|
||||
:param boxed_type: class literal.
|
||||
|
||||
:return: deserialized dict.
|
||||
:rtype: dict
|
||||
"""
|
||||
return {k: _deserialize(v, boxed_type)
|
||||
for k, v in data.items() }
|
||||
13
demo_server/requirements.txt
Normal file
13
demo_server/requirements.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
connexion[swagger-ui] >= 2.6.0; python_version>="3.6"
|
||||
# 2.3 is the last version that supports python 3.4-3.5
|
||||
connexion[swagger-ui] <= 2.3.0; python_version=="3.5" or python_version=="3.4"
|
||||
# prevent breaking dependencies from advent of connexion>=3.0
|
||||
connexion[swagger-ui] <= 2.14.2; python_version>"3.4"
|
||||
# connexion requires werkzeug but connexion < 2.4.0 does not install werkzeug
|
||||
# we must peg werkzeug versions below to fix connexion
|
||||
# https://github.com/zalando/connexion/pull/1044
|
||||
werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4"
|
||||
swagger-ui-bundle >= 0.0.2
|
||||
python_dateutil >= 2.6.0
|
||||
setuptools >= 21.0.0
|
||||
Flask == 2.1.1
|
||||
0
demo_server/server.py
Normal file
0
demo_server/server.py
Normal file
37
demo_server/setup.py
Normal file
37
demo_server/setup.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
NAME = "openapi_server"
|
||||
VERSION = "1.0.0"
|
||||
|
||||
# To install the library, run the following
|
||||
#
|
||||
# python setup.py install
|
||||
#
|
||||
# prerequisite: setuptools
|
||||
# http://pypi.python.org/pypi/setuptools
|
||||
|
||||
REQUIRES = [
|
||||
"connexion>=2.0.2",
|
||||
"swagger-ui-bundle>=0.0.2",
|
||||
"python_dateutil>=2.6.0"
|
||||
]
|
||||
|
||||
setup(
|
||||
name=NAME,
|
||||
version=VERSION,
|
||||
description="PeerNetService API",
|
||||
author_email="",
|
||||
url="",
|
||||
keywords=["OpenAPI", "PeerNetService API"],
|
||||
install_requires=REQUIRES,
|
||||
packages=find_packages(),
|
||||
package_data={'': ['openapi/openapi.yaml']},
|
||||
include_package_data=True,
|
||||
entry_points={
|
||||
'console_scripts': ['openapi_server=openapi_server.__main__:main']},
|
||||
long_description="""\
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
"""
|
||||
)
|
||||
|
||||
4
demo_server/test-requirements.txt
Normal file
4
demo_server/test-requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
pytest~=7.1.0
|
||||
pytest-cov>=2.8.1
|
||||
pytest-randomly>=1.2.3
|
||||
Flask-Testing==0.8.1
|
||||
94
demo_server/test.sh
Executable file
94
demo_server/test.sh
Executable file
@@ -0,0 +1,94 @@
|
||||
#!/bin/zsh
|
||||
|
||||
curl -X 'POST' \
|
||||
'http://localhost:8080/v1/servers' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "my server",
|
||||
"rooms": [
|
||||
"myroom"
|
||||
],
|
||||
"authToken": "string",
|
||||
"displayName": "Hello",
|
||||
"services": [
|
||||
{
|
||||
"name": "http1",
|
||||
"protocol": "peernet.http",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
}'
|
||||
|
||||
curl -X 'GET' \
|
||||
'http://localhost:8080/v1/rooms/myroom' \
|
||||
-H 'accept: application/json'
|
||||
|
||||
# Simulate a knock
|
||||
|
||||
curl -X 'POST' \
|
||||
'http://127.0.0.1:8080/v1/servers/my%20server/services/http1/knocks' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "knockname",
|
||||
"offer": {
|
||||
"name": "name1",
|
||||
"sdpType": "string",
|
||||
"sdp": "string"
|
||||
},
|
||||
"answer": {
|
||||
"name": "string",
|
||||
"sdpType": "string",
|
||||
"sdp": "string"
|
||||
}
|
||||
}'
|
||||
|
||||
echo "http://127.0.0.1:8080/v1/servers/my%20server/services/http1/knocks"
|
||||
curl -X 'GET' \
|
||||
'http://127.0.0.1:8080/v1/servers/my%20server/services/http1/knocks' \
|
||||
-H 'accept: application/json'
|
||||
echo
|
||||
|
||||
echo "http://127.0.0.1:8080/v1/servers/my%20server/services/http1/knocks/knockname"
|
||||
curl -X 'PATCH' \
|
||||
'http://127.0.0.1:8080/v1/servers/my%20server/services/http1/knocks/knockname' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "knockname",
|
||||
"offer": {
|
||||
"name": "name1",
|
||||
"sdpType": "string",
|
||||
"sdp": "string"
|
||||
},
|
||||
"offer": {
|
||||
"name": "name1",
|
||||
"sdpType": "string",
|
||||
"sdp": "string"
|
||||
},
|
||||
"answer": {
|
||||
"name": "name2",
|
||||
"sdpType": "name2",
|
||||
"sdp": "string"
|
||||
}
|
||||
}'
|
||||
|
||||
curl -X 'POST' \
|
||||
'http://127.0.0.1:8080/v1/sessions/name2/candidates' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "mycandidate",
|
||||
"candidate": "string",
|
||||
"sdpMid": "string",
|
||||
"sdpLineIndex": 0,
|
||||
"usernameFragment": "string"
|
||||
}'
|
||||
|
||||
curl -X 'GET' \
|
||||
'http://127.0.0.1:8080/v1/sessions/name2/claim/candidates' \
|
||||
-H 'accept: application/json'
|
||||
curl -X 'GET' \
|
||||
'http://127.0.0.1:8080/v1/sessions/name2/claim/candidates' \
|
||||
-H 'accept: application/json'
|
||||
11
demo_server/tox.ini
Normal file
11
demo_server/tox.ini
Normal file
@@ -0,0 +1,11 @@
|
||||
[tox]
|
||||
envlist = py3
|
||||
skipsdist=True
|
||||
|
||||
[testenv]
|
||||
deps=-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
{toxinidir}
|
||||
|
||||
commands=
|
||||
pytest --cov=openapi_server
|
||||
189
proto/peernet_service.proto
Normal file
189
proto/peernet_service.proto
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
syntax = "proto2";
|
||||
package peernet;
|
||||
|
||||
option go_package = "peernet/";
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
|
||||
service PeerNetService {
|
||||
rpc GetRoom(GetRoomRequest) returns (Room) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/{name=rooms/*}"
|
||||
};
|
||||
};
|
||||
|
||||
rpc CreateServer(CreateServerRequest) returns (Server) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/servers"
|
||||
body: "server"
|
||||
};
|
||||
};
|
||||
rpc DeleteServer(DeleteServerRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v1/servers/*"
|
||||
};
|
||||
};
|
||||
|
||||
rpc CreateService(CreateServiceRequest) returns (Service) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/{parent=servers/*}/services"
|
||||
body: "service"
|
||||
};
|
||||
};
|
||||
rpc DeleteService(DeleteServiceRequest) returns (google.protobuf.Empty) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v1/{name=servers/*/services/*}"
|
||||
};
|
||||
};
|
||||
|
||||
// Creates a knock that will be answered by the peer; the signaler may
|
||||
// delete the knock, regardless of the state, when it ages.
|
||||
rpc CreateKnock(CreateKnockRequest) returns (Knock){
|
||||
option (google.api.http) = {
|
||||
post: "/v1/{parent=servers/*/services/*}/knocks"
|
||||
body: "knock"
|
||||
};
|
||||
};
|
||||
rpc UpdateKnock(UpdateKnockRequest) returns (Knock) {
|
||||
option (google.api.http) = {
|
||||
patch: "/v1/{knock.name=servers/*/services/*/knocks/*}"
|
||||
body: "knock"
|
||||
};
|
||||
};
|
||||
rpc ListKnocks(ListKnocksRequest) returns (ListKnocksResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/{parent=servers/*/services/*}/knocks"
|
||||
};
|
||||
};
|
||||
rpc GetKnock(GetKnockRequest) returns (Knock) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/{name=servers/*/services/*/knocks/*}"
|
||||
};
|
||||
};
|
||||
|
||||
rpc CreateIceCandidate(CreateIceCandidateRequest) returns (IceCandidate) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/{parent=sessions/*}/candidates"
|
||||
body: "ice_candidate"
|
||||
};
|
||||
};;
|
||||
// Acts as both List and Delete atomically.
|
||||
rpc ClaimIceCandidates(ClaimIceCandidatesRequest) returns (ClaimIceCandidatesResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v1/{parent=sessions/*}/claim/candidates"
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
message GetKnockRequest {
|
||||
required string name = 1;
|
||||
}
|
||||
|
||||
message GetRoomRequest {
|
||||
required string name = 1;
|
||||
}
|
||||
|
||||
message CreateServerRequest {
|
||||
required Server server = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
}
|
||||
|
||||
message DeleteServerRequest {
|
||||
required string name = 1;
|
||||
}
|
||||
|
||||
message CreateServiceRequest {
|
||||
required Service service = 1;
|
||||
}
|
||||
|
||||
message DeleteServiceRequest {
|
||||
required string name = 1;
|
||||
}
|
||||
|
||||
message CreateKnockRequest {
|
||||
required Knock knock = 1;
|
||||
}
|
||||
|
||||
message UpdateKnockRequest {
|
||||
required Knock knock = 1;
|
||||
}
|
||||
|
||||
message ListKnocksRequest { }
|
||||
|
||||
message ListKnocksResponse {
|
||||
repeated Knock knocks = 1;
|
||||
}
|
||||
|
||||
message CreateIceCandidateRequest {
|
||||
required IceCandidate ice_candidate = 1;
|
||||
}
|
||||
|
||||
message ClaimIceCandidatesRequest { }
|
||||
|
||||
message ClaimIceCandidatesResponse {
|
||||
repeated IceCandidate ice_candidates = 1;
|
||||
}
|
||||
|
||||
message Room {
|
||||
required string name = 1;
|
||||
required string display_name = 2;
|
||||
|
||||
repeated Server servers = 3;
|
||||
}
|
||||
|
||||
message Server {
|
||||
required string name = 1;
|
||||
|
||||
// Tracks which rooms the server should be listed in; this will not
|
||||
// be set when a room is listed to preserve privacy of servers.
|
||||
repeated string rooms = 2 [(google.api.field_behavior) = INPUT_ONLY];
|
||||
|
||||
// Used to authenticate requests which access knocks for this server
|
||||
// or attempt to update, delete or create services.
|
||||
// In future calls, add a header with the format:
|
||||
// Authorization: Bearer <auth_token>
|
||||
required string auth_token = 3 [(google.api.field_behavior) = INPUT_ONLY];
|
||||
|
||||
required string display_name = 4;
|
||||
|
||||
repeated Service services = 5;
|
||||
}
|
||||
|
||||
message Service {
|
||||
required string name = 1;
|
||||
required string protocol = 2;
|
||||
required string version = 3;
|
||||
|
||||
// Used to define custom fields per-protocol/version.
|
||||
// We use unverified extensions because this system is meant
|
||||
// to be distributed, with no central owner, hence, no singular
|
||||
// authority to hand out field numbers. Instead, implementations
|
||||
// should use the protocol/version to scope what values are expected.
|
||||
extensions 100 to max [verification = UNVERIFIED];
|
||||
}
|
||||
|
||||
message Knock {
|
||||
required string name = 1;
|
||||
// The service being connected too
|
||||
optional IceSessionDescription offer = 2;
|
||||
optional IceSessionDescription answer = 3;
|
||||
}
|
||||
|
||||
message IceSessionDescription {
|
||||
// A unique identifier which can be used to send ICE candidates
|
||||
// Maps to the session name
|
||||
required string name = 1;
|
||||
// Used to construct the remote description in WebRTC
|
||||
required int64 sdp_type = 3;
|
||||
required string sdp = 4;
|
||||
}
|
||||
|
||||
message IceCandidate {
|
||||
required string name = 1;
|
||||
required string candidate = 2;
|
||||
optional string sdp_mid = 3;
|
||||
optional int32 sdp_line_index = 4;
|
||||
optional string username_fragment = 5;
|
||||
}
|
||||
Reference in New Issue
Block a user