From 0c90b6f9581227df91bc3ec66c249eb0b5777a3c Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Sun, 25 Feb 2024 20:55:49 -0800 Subject: [PATCH 1/7] Library updates and pydantic 2 changes Signed-off-by: Lucas ONeil --- oidc-controller/api/core/config.py | 10 +++++----- oidc-controller/api/core/models.py | 2 +- oidc-controller/api/verificationConfigs/models.py | 2 +- oidc-controller/requirements.txt | 13 +++++++------ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/oidc-controller/api/core/config.py b/oidc-controller/api/core/config.py index c9087e96..2a621d9b 100644 --- a/oidc-controller/api/core/config.py +++ b/oidc-controller/api/core/config.py @@ -7,9 +7,9 @@ from functools import lru_cache from pathlib import Path from typing import Optional, Union +from pydantic_settings import BaseSettings import structlog -from pydantic import BaseSettings # Removed in later versions of python @@ -162,7 +162,7 @@ class GlobalConfig(BaseSettings): "CONTROLLER_CAMERA_REDIRECT_URL" ) # The number of seconds to wait for a presentation to be verified, Default: 10 - CONTROLLER_PRESENTATION_EXPIRE_TIME: Union[int, str] = os.environ.get( + CONTROLLER_PRESENTATION_EXPIRE_TIME: int = os.environ.get( "CONTROLLER_PRESENTATION_EXPIRE_TIME", 10 ) @@ -188,11 +188,11 @@ class GlobalConfig(BaseSettings): DEFAULT_PAGE_SIZE: Union[int, str] = os.environ.get("DEFAULT_PAGE_SIZE", 10) # openssl rand -hex 32 - SIGNING_KEY_SIZE = os.environ.get("SIGNING_KEY_SIZE", 2048) + SIGNING_KEY_SIZE: int = os.environ.get("SIGNING_KEY_SIZE", 2048) # SIGNING_KEY_FILEPATH expects complete path including filename and extension. SIGNING_KEY_FILEPATH: Optional[str] = os.environ.get("SIGNING_KEY_FILEPATH") SIGNING_KEY_ALGORITHM: str = os.environ.get("SIGNING_KEY_ALGORITHM", "RS256") - SUBJECT_ID_HASH_SALT = os.environ.get("SUBJECT_ID_HASH_SALT", "test_hash_salt") + SUBJECT_ID_HASH_SALT: str = os.environ.get("SUBJECT_ID_HASH_SALT", "test_hash_salt") # OIDC Client Settings OIDC_CLIENT_ID: str = os.environ.get("OIDC_CLIENT_ID", "keycloak") @@ -221,7 +221,7 @@ class LocalConfig(GlobalConfig): """Local configurations.""" DEBUG: bool = True - DB_ECHO_LOG = True + DB_ECHO_LOG: bool = True ENVIRONMENT: EnvironmentEnum = EnvironmentEnum.LOCAL diff --git a/oidc-controller/api/core/models.py b/oidc-controller/api/core/models.py index 519d2456..695ecf2b 100644 --- a/oidc-controller/api/core/models.py +++ b/oidc-controller/api/core/models.py @@ -18,7 +18,7 @@ def validate(cls, v): return ObjectId(v) @classmethod - def __modify_schema__(cls, field_schema): + def __get_pydantic_json_schema__(cls, field_schema): field_schema.update(type="string") diff --git a/oidc-controller/api/verificationConfigs/models.py b/oidc-controller/api/verificationConfigs/models.py index cfb318d2..9f4400c7 100644 --- a/oidc-controller/api/verificationConfigs/models.py +++ b/oidc-controller/api/verificationConfigs/models.py @@ -32,7 +32,7 @@ class ReqPred(BaseModel): class VerificationProofRequest(BaseModel): name: Optional[str] - version: str = Field(regex="[0-9](.[0.9])*", example="0.0.1") + version: str = Field(pattern="[0-9](.[0.9])*", example="0.0.1") non_revoked: Optional[str] requested_attributes: List[ReqAttr] requested_predicates: List[ReqPred] diff --git a/oidc-controller/requirements.txt b/oidc-controller/requirements.txt index d4cab51e..853f7216 100644 --- a/oidc-controller/requirements.txt +++ b/oidc-controller/requirements.txt @@ -1,11 +1,12 @@ -fastapi==0.96.0 -jinja2==3.1.2 -oic==1.6.0 -pymongo==4.3.3 -pyop==3.4.0 -python-multipart==0.0.6 # required by fastapi to serve/upload files +fastapi==0.109.2 +jinja2==3.1.3 +oic==1.6.1 +pymongo==4.6.2 +pyop==3.4.1 +python-multipart==0.0.7 # required by fastapi to serve/upload files qrcode[pil]==7.4.2 structlog==23.1.0 uvicorn[standard]==0.22.0 python-socketio==5.8.0 # required to run websockets canonicaljson==2.0.0 # used to provide unique consistent user identifiers +pydantic-settings==2.2.1 From e9617cfd21a8a7a21fb391ee2ddff5c71a3b4918 Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 27 Mar 2024 09:52:30 -0700 Subject: [PATCH 2/7] Optional default changes for pydantic2 Signed-off-by: Lucas ONeil --- .../api/clientConfigurations/models.py | 6 +++--- .../api/core/aries/service_decorator.py | 8 ++++---- .../api/verificationConfigs/models.py | 20 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/oidc-controller/api/clientConfigurations/models.py b/oidc-controller/api/clientConfigurations/models.py index 295a88f5..6e9db6cf 100644 --- a/oidc-controller/api/clientConfigurations/models.py +++ b/oidc-controller/api/clientConfigurations/models.py @@ -41,11 +41,11 @@ class ClientConfigurationRead(ClientConfigurationBase): class ClientConfigurationPatch(ClientConfigurationBase): - client_id: Optional[str] - client_name: Optional[str] + client_id: Optional[str] = None + client_name: Optional[str] = None response_types: Optional[List[str]] redirect_uris: Optional[List[str]] token_endpoint_auth_method: Optional[TOKENENDPOINTAUTHMETHODS] - client_secret: Optional[str] + client_secret: Optional[str] = None pass diff --git a/oidc-controller/api/core/aries/service_decorator.py b/oidc-controller/api/core/aries/service_decorator.py index 7a64ae6a..322b899c 100644 --- a/oidc-controller/api/core/aries/service_decorator.py +++ b/oidc-controller/api/core/aries/service_decorator.py @@ -4,9 +4,9 @@ class ServiceDecorator(BaseModel): # https://github.com/hyperledger/aries-rfcs/tree/main/features/0056-service-decorator - recipient_keys: Optional[List[str]] = Field(alias="recipientKeys") - routing_keys: Optional[List[str]] = Field(alias="routingKeys") - service_endpoint: Optional[str] = Field(alias="serviceEndpoint") + recipient_keys: Optional[List[str]] = Field(default=None, alias="recipientKeys") + routing_keys: Optional[List[str]] = Field(default=None, alias="routingKeys") + service_endpoint: Optional[str] = Field(default=None, alias="serviceEndpoint") class Config: allow_population_by_field_name = True @@ -16,7 +16,7 @@ class OOBServiceDecorator(ServiceDecorator): # ServiceDecorator recipient_keys: Optional[List[str]] routing_keys: Optional[List[str]] = Field(default=[]) - service_endpoint: Optional[str] + service_endpoint: Optional[str] = None id: str = Field(default="did:vc-authn-oidc:123456789zyxwvutsr#did-communication") type: str = Field(default="did-communication") priority: int = 0 diff --git a/oidc-controller/api/verificationConfigs/models.py b/oidc-controller/api/verificationConfigs/models.py index 9f4400c7..b8de8e11 100644 --- a/oidc-controller/api/verificationConfigs/models.py +++ b/oidc-controller/api/verificationConfigs/models.py @@ -8,32 +8,32 @@ # Slightly modified from ACAPY models. class AttributeFilter(BaseModel): - schema_id: Optional[str] - cred_def_id: Optional[str] - schema_name: Optional[str] - schema_issuer_did: Optional[str] - schema_version: Optional[str] - issuer_did: Optional[str] + schema_id: Optional[str] = None + cred_def_id: Optional[str] = None + schema_name: Optional[str] = None + schema_issuer_did: Optional[str] = None + schema_version: Optional[str] = None + issuer_did: Optional[str] = None class ReqAttr(BaseModel): names: List[str] - label: Optional[str] + label: Optional[str] = None restrictions: List[AttributeFilter] class ReqPred(BaseModel): name: str - label: Optional[str] + label: Optional[str] = None restrictions: List[AttributeFilter] p_value: str p_type: str class VerificationProofRequest(BaseModel): - name: Optional[str] + name: Optional[str] = None version: str = Field(pattern="[0-9](.[0.9])*", example="0.0.1") - non_revoked: Optional[str] + non_revoked: Optional[str] = None requested_attributes: List[ReqAttr] requested_predicates: List[ReqPred] From eebf2f513ded58c7faec730fddbbd3833e6b32be Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 27 Mar 2024 10:35:12 -0700 Subject: [PATCH 3/7] Pydantic 2 config changes Signed-off-by: Lucas ONeil --- oidc-controller/api/authSessions/models.py | 5 ++--- oidc-controller/api/clientConfigurations/models.py | 6 ++---- oidc-controller/api/core/aries/out_of_band.py | 8 +++----- .../api/core/aries/present_proof_presentation.py | 5 ++--- oidc-controller/api/core/aries/service_decorator.py | 8 +++----- oidc-controller/api/core/config.py | 4 ++-- oidc-controller/api/core/models.py | 5 ++--- oidc-controller/api/verificationConfigs/models.py | 7 +++---- 8 files changed, 19 insertions(+), 29 deletions(-) diff --git a/oidc-controller/api/authSessions/models.py b/oidc-controller/api/authSessions/models.py index 67e84c15..017010da 100644 --- a/oidc-controller/api/authSessions/models.py +++ b/oidc-controller/api/authSessions/models.py @@ -4,7 +4,7 @@ from api.core.acapy.client import AcapyClient from api.core.models import UUIDModel -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from ..core.config import settings @@ -27,8 +27,7 @@ class AuthSessionBase(BaseModel): response_url: str presentation_request_msg: Optional[dict] = None - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) class AuthSession(AuthSessionBase, UUIDModel): diff --git a/oidc-controller/api/clientConfigurations/models.py b/oidc-controller/api/clientConfigurations/models.py index 6e9db6cf..8934390a 100644 --- a/oidc-controller/api/clientConfigurations/models.py +++ b/oidc-controller/api/clientConfigurations/models.py @@ -1,7 +1,7 @@ from enum import Enum from typing import List, Optional -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from ..core.config import settings from .examples import ex_client_config @@ -27,9 +27,7 @@ class ClientConfigurationBase(BaseModel): client_secret: str = Field(default=settings.OIDC_CLIENT_SECRET) - class Config: - allow_population_by_field_name = True - schema_extra = {"example": ex_client_config} + model_config = ConfigDict(populate_by_name=True, json_schema_extra={"example": ex_client_config}) class ClientConfiguration(ClientConfigurationBase): diff --git a/oidc-controller/api/core/aries/out_of_band.py b/oidc-controller/api/core/aries/out_of_band.py index 6c17ab99..c24f3478 100644 --- a/oidc-controller/api/core/aries/out_of_band.py +++ b/oidc-controller/api/core/aries/out_of_band.py @@ -1,5 +1,5 @@ from typing import Dict, List, Union -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from .service_decorator import OOBServiceDecorator @@ -8,8 +8,7 @@ class OutOfBandPresentProofAttachment(BaseModel): mime_type: str = Field(default="application/json", alias="mime-type") data: Dict - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) class OutOfBandMessage(BaseModel): @@ -28,5 +27,4 @@ class OutOfBandMessage(BaseModel): ) services: List[Union[OOBServiceDecorator, str]] = Field(alias="services") - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) diff --git a/oidc-controller/api/core/aries/present_proof_presentation.py b/oidc-controller/api/core/aries/present_proof_presentation.py index 1bf383ce..a9a8550e 100644 --- a/oidc-controller/api/core/aries/present_proof_presentation.py +++ b/oidc-controller/api/core/aries/present_proof_presentation.py @@ -2,7 +2,7 @@ import base64 from typing import Optional, List -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from api.core.aries import PresentProofv10Attachment, ServiceDecorator @@ -19,8 +19,7 @@ class PresentationRequestMessage(BaseModel): comment: Optional[str] = None service: Optional[ServiceDecorator] = Field(alias="~service") - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) def b64_str(self): # object->dict->jsonString->ascii->ENCODE->ascii diff --git a/oidc-controller/api/core/aries/service_decorator.py b/oidc-controller/api/core/aries/service_decorator.py index 322b899c..5b2c4c29 100644 --- a/oidc-controller/api/core/aries/service_decorator.py +++ b/oidc-controller/api/core/aries/service_decorator.py @@ -1,5 +1,5 @@ from typing import List, Optional -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class ServiceDecorator(BaseModel): @@ -8,8 +8,7 @@ class ServiceDecorator(BaseModel): routing_keys: Optional[List[str]] = Field(default=None, alias="routingKeys") service_endpoint: Optional[str] = Field(default=None, alias="serviceEndpoint") - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) class OOBServiceDecorator(ServiceDecorator): @@ -21,5 +20,4 @@ class OOBServiceDecorator(ServiceDecorator): type: str = Field(default="did-communication") priority: int = 0 - class Config: - allow_population_by_field_name = True + model_config = ConfigDict(populate_by_name=True) diff --git a/oidc-controller/api/core/config.py b/oidc-controller/api/core/config.py index 2a621d9b..04e49300 100644 --- a/oidc-controller/api/core/config.py +++ b/oidc-controller/api/core/config.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import Optional, Union from pydantic_settings import BaseSettings +from pydantic import ConfigDict import structlog @@ -213,8 +214,7 @@ class GlobalConfig(BaseSettings): ) SET_NON_REVOKED: bool = strtobool(os.environ.get("SET_NON_REVOKED", True)) - class Config: - case_sensitive = True + model_config = ConfigDict(case_sensitive=True) class LocalConfig(GlobalConfig): diff --git a/oidc-controller/api/core/models.py b/oidc-controller/api/core/models.py index 695ecf2b..7c47e73d 100644 --- a/oidc-controller/api/core/models.py +++ b/oidc-controller/api/core/models.py @@ -2,7 +2,7 @@ from typing import TypedDict from bson import ObjectId -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from pyop.userinfo import Userinfo @@ -36,8 +36,7 @@ class StatusMessage(BaseModel): class UUIDModel(BaseModel): id: PyObjectId = Field(default_factory=PyObjectId, alias="_id") - class Config: - json_encoders = {ObjectId: str} + model_config = ConfigDict(json_encoders={ObjectId: str}) class TimestampModel(BaseModel): diff --git a/oidc-controller/api/verificationConfigs/models.py b/oidc-controller/api/verificationConfigs/models.py index b8de8e11..44b5812b 100644 --- a/oidc-controller/api/verificationConfigs/models.py +++ b/oidc-controller/api/verificationConfigs/models.py @@ -1,6 +1,6 @@ import time from typing import Optional, List -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from .examples import ex_ver_config from ..core.config import settings @@ -69,9 +69,8 @@ def generate_proof_request(self): "to": int(time.time()), } return result - - class Config: - schema_extra = {"example": ex_ver_config} + + model_config = ConfigDict(schema_extra={"example": ex_ver_config}) class VerificationConfig(VerificationConfigBase): From b75b05db95cbeeac7fdb7303a4bd4fc9d293963d Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 27 Mar 2024 10:40:03 -0700 Subject: [PATCH 4/7] Optional fixes from pydantic2 bump-pydantic Signed-off-by: Lucas ONeil --- oidc-controller/api/clientConfigurations/models.py | 6 +++--- oidc-controller/api/core/acapy/models.py | 2 +- .../api/core/aries/present_proof_presentation.py | 2 +- oidc-controller/api/core/aries/service_decorator.py | 2 +- oidc-controller/api/verificationConfigs/models.py | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/oidc-controller/api/clientConfigurations/models.py b/oidc-controller/api/clientConfigurations/models.py index 8934390a..b35c3588 100644 --- a/oidc-controller/api/clientConfigurations/models.py +++ b/oidc-controller/api/clientConfigurations/models.py @@ -41,9 +41,9 @@ class ClientConfigurationRead(ClientConfigurationBase): class ClientConfigurationPatch(ClientConfigurationBase): client_id: Optional[str] = None client_name: Optional[str] = None - response_types: Optional[List[str]] - redirect_uris: Optional[List[str]] - token_endpoint_auth_method: Optional[TOKENENDPOINTAUTHMETHODS] + response_types: Optional[List[str]] = None + redirect_uris: Optional[List[str]] = None + token_endpoint_auth_method: Optional[TOKENENDPOINTAUTHMETHODS] = None client_secret: Optional[str] = None pass diff --git a/oidc-controller/api/core/acapy/models.py b/oidc-controller/api/core/acapy/models.py index da48a16d..7b4df94c 100644 --- a/oidc-controller/api/core/acapy/models.py +++ b/oidc-controller/api/core/acapy/models.py @@ -10,7 +10,7 @@ class WalletDid(BaseModel): class WalletDidPublicResponse(BaseModel): - result: Optional[WalletDid] + result: Optional[WalletDid] = None class CreatePresentationResponse(BaseModel): diff --git a/oidc-controller/api/core/aries/present_proof_presentation.py b/oidc-controller/api/core/aries/present_proof_presentation.py index a9a8550e..95b01b5e 100644 --- a/oidc-controller/api/core/aries/present_proof_presentation.py +++ b/oidc-controller/api/core/aries/present_proof_presentation.py @@ -17,7 +17,7 @@ class PresentationRequestMessage(BaseModel): alias="request_presentations~attach" ) comment: Optional[str] = None - service: Optional[ServiceDecorator] = Field(alias="~service") + service: Optional[ServiceDecorator] = Field(None, alias="~service") model_config = ConfigDict(populate_by_name=True) diff --git a/oidc-controller/api/core/aries/service_decorator.py b/oidc-controller/api/core/aries/service_decorator.py index 5b2c4c29..937edc18 100644 --- a/oidc-controller/api/core/aries/service_decorator.py +++ b/oidc-controller/api/core/aries/service_decorator.py @@ -13,7 +13,7 @@ class ServiceDecorator(BaseModel): class OOBServiceDecorator(ServiceDecorator): # ServiceDecorator - recipient_keys: Optional[List[str]] + recipient_keys: Optional[List[str]] = None routing_keys: Optional[List[str]] = Field(default=[]) service_endpoint: Optional[str] = None id: str = Field(default="did:vc-authn-oidc:123456789zyxwvutsr#did-communication") diff --git a/oidc-controller/api/verificationConfigs/models.py b/oidc-controller/api/verificationConfigs/models.py index 44b5812b..6faf0e4b 100644 --- a/oidc-controller/api/verificationConfigs/models.py +++ b/oidc-controller/api/verificationConfigs/models.py @@ -32,7 +32,7 @@ class ReqPred(BaseModel): class VerificationProofRequest(BaseModel): name: Optional[str] = None - version: str = Field(pattern="[0-9](.[0.9])*", example="0.0.1") + version: str = Field(pattern="[0-9](.[0.9])*", examples=["0.0.1"]) non_revoked: Optional[str] = None requested_attributes: List[ReqAttr] requested_predicates: List[ReqPred] @@ -82,7 +82,7 @@ class VerificationConfigRead(VerificationConfigBase): class VerificationConfigPatch(VerificationConfigBase): - subject_identifier: Optional[str] = Field() - proof_request: Optional[VerificationProofRequest] = Field() + subject_identifier: Optional[str] = Field(None) + proof_request: Optional[VerificationProofRequest] = Field(None) pass From dbcf95f6356335cf463ec229ac68fe689aa4191c Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 27 Mar 2024 11:13:32 -0700 Subject: [PATCH 5/7] validator Signed-off-by: Lucas ONeil --- oidc-controller/api/core/models.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/oidc-controller/api/core/models.py b/oidc-controller/api/core/models.py index 7c47e73d..12d11bc4 100644 --- a/oidc-controller/api/core/models.py +++ b/oidc-controller/api/core/models.py @@ -4,15 +4,16 @@ from bson import ObjectId from pydantic import BaseModel, ConfigDict, Field from pyop.userinfo import Userinfo +from pydantic_core import core_schema class PyObjectId(ObjectId): @classmethod - def __get_validators__(cls): - yield cls.validate + def __get_pydantic_core_schema__(cls, source_type, handler) -> core_schema.CoreSchema: + return core_schema.general_plain_validator_function(cls.validate) @classmethod - def validate(cls, v): + def validate(cls, v, info): if not ObjectId.is_valid(v): raise ValueError("Invalid objectid") return ObjectId(v) From fa3162fdad994a2359835f2ee156178ab0121f1f Mon Sep 17 00:00:00 2001 From: Lucas ONeil Date: Wed, 27 Mar 2024 14:02:56 -0700 Subject: [PATCH 6/7] Socket.io updates Signed-off-by: Lucas ONeil --- oidc-controller/api/routers/socketio.py | 2 +- oidc-controller/api/templates/verified_credentials.html | 4 +++- oidc-controller/api/verificationConfigs/models.py | 2 +- oidc-controller/requirements.txt | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/oidc-controller/api/routers/socketio.py b/oidc-controller/api/routers/socketio.py index f92eed00..a43838b6 100644 --- a/oidc-controller/api/routers/socketio.py +++ b/oidc-controller/api/routers/socketio.py @@ -9,7 +9,7 @@ sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*') -sio_app = socketio.ASGIApp(socketio_server=sio) +sio_app = socketio.ASGIApp(socketio_server=sio, socketio_path='/ws/socket.io') @sio.event async def connect(sid, socket): diff --git a/oidc-controller/api/templates/verified_credentials.html b/oidc-controller/api/templates/verified_credentials.html index 19b57eb4..163a1022 100644 --- a/oidc-controller/api/templates/verified_credentials.html +++ b/oidc-controller/api/templates/verified_credentials.html @@ -2,7 +2,9 @@ Scan QR Code - + Date: Thu, 28 Mar 2024 09:21:31 -0700 Subject: [PATCH 7/7] Remove test app Signed-off-by: Lucas ONeil --- .../api/routers/quick-socket/app.py | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100755 oidc-controller/api/routers/quick-socket/app.py diff --git a/oidc-controller/api/routers/quick-socket/app.py b/oidc-controller/api/routers/quick-socket/app.py deleted file mode 100755 index 833d52a5..00000000 --- a/oidc-controller/api/routers/quick-socket/app.py +++ /dev/null @@ -1,65 +0,0 @@ -import uvicorn -from fastapi import FastAPI -from fastapi.responses import HTMLResponse -import socketio # Installed with 'pip install python-socketio` - -html = """ - - - - - Socket.io Test - - - - -
- - -
- - -""" - -# Create a FastAPI instance -app = FastAPI() - -@app.get("/") -async def root(): - return HTMLResponse(html) - -# Create a test websocket server -# TODO: This needs to be shared with oidc.py and acapy_handler.py -sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*') - -@sio.event -async def connect(sid, socket): - print('connected', sid) - await sio.emit('message', {'data': "I'm a real boy!"}) - -@sio.event -def disconnected(sid): - print('disconnected', sid) - -sio_app = socketio.ASGIApp(socketio_server=sio) - -app.mount('/ws', sio_app) - -uvicorn.run(app, host="localhost", port=5100) \ No newline at end of file