Added create_entity
Some checks failed
checks-impure / test (pull_request) Successful in 30s
checks / test (pull_request) Failing after 3h13m7s

This commit is contained in:
2023-11-26 20:54:57 +01:00
parent 80ccaa83d3
commit d1a3a5381a
8 changed files with 200 additions and 128 deletions

View File

@@ -14,6 +14,7 @@ from .assets import asset_path
from .error_handlers import clan_error_handler from .error_handlers import clan_error_handler
from .routers import health, root, socket_manager2, sql_connect # sql router hinzufügen from .routers import health, root, socket_manager2, sql_connect # sql router hinzufügen
from .sql_db import engine from .sql_db import engine
from .tags import tags_metadata
origins = [ origins = [
"http://localhost:3000", "http://localhost:3000",
@@ -55,6 +56,9 @@ def setup_app() -> FastAPI:
app.mount("/static", StaticFiles(directory=asset_path()), name="static") app.mount("/static", StaticFiles(directory=asset_path()), name="static")
# Add tag descriptions to the OpenAPI schema
app.openapi_tags = tags_metadata
for route in app.routes: for route in app.routes:
if isinstance(route, APIRoute): if isinstance(route, APIRoute):
route.operation_id = route.name # in this case, 'read_items' route.operation_id = route.name # in this case, 'read_items'

View File

@@ -1,6 +1,6 @@
from fastapi import APIRouter from fastapi import APIRouter
from ..api_outputs import Machine, Status from ..schemas import Machine, Status
router = APIRouter() router = APIRouter()

View File

@@ -1,79 +0,0 @@
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi import APIRouter, Response
router = APIRouter()
html = """
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
</head>
<body>
<h1>WebSocket Chat</h1>
<h2>Your ID: <span id="ws-id"></span></h2>
<form action="" onsubmit="sendMessage(event)">
<input type="text" id="messageText" autocomplete="off"/>
<button>Send</button>
</form>
<ul id='messages'>
</ul>
<script>
var client_id = Date.now()
document.querySelector("#ws-id").textContent = client_id;
var ws = new WebSocket(`ws://localhost:2979/ws/${client_id}`);
ws.onmessage = function(event) {
var messages = document.getElementById('messages')
var message = document.createElement('li')
var content = document.createTextNode(event.data)
message.appendChild(content)
messages.appendChild(message)
};
function sendMessage(event) {
var input = document.getElementById("messageText")
ws.send(input.value)
input.value = ''
event.preventDefault()
}
</script>
</body>
</html>
"""
class ConnectionManager:
def __init__(self) -> None:
self.active_connections: list[WebSocket] = []
async def connect(self, websocket: WebSocket) -> None:
await websocket.accept()
self.active_connections.append(websocket)
def disconnect(self, websocket: WebSocket) -> None:
self.active_connections.remove(websocket)
async def send_personal_message(self, message: str, websocket: WebSocket) -> None:
await websocket.send_text(message)
async def broadcast(self, message: str) -> None:
for connection in self.active_connections:
await connection.send_text(message)
manager = ConnectionManager()
@router.get("/ws_example")
async def get() -> HTMLResponse:
return HTMLResponse(html)
@router.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int) -> None:
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_text()
await manager.send_personal_message(f"You wrote: {data}", websocket)
await manager.broadcast(f"Client #{client_id} says: {data}")
except WebSocketDisconnect:
manager.disconnect(websocket)
await manager.broadcast(f"Client #{client_id} left the chat")

View File

@@ -4,22 +4,39 @@ from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .. import sql_crud, sql_db, sql_models from .. import sql_crud, sql_db, sql_models
from ..api_outputs import Producer, ProducerCreate from ..schemas import Entity, EntityCreate
from ..tags import Tags
router = APIRouter() router = APIRouter()
@router.get("/get_producers", response_model=List[Producer]) # @router.get("/api/v1/get_producers", response_model=List[Producer], tags=[Tags.producers])
def get_producers( # def get_producers(
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db) # skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
) -> List[sql_models.Producer]: # ) -> List[sql_models.Producer]:
producers = sql_crud.get_producers(db, skip=skip, limit=limit) # producers = sql_crud.get_producers(db, skip=skip, limit=limit)
return producers # return producers
@router.post("/create_producers", response_model=Producer) # @router.post("/api/v1/create_producer", response_model=Producer, tags=[Tags.producers])
def create_producers( # def create_producer(
producer: ProducerCreate, db: Session = Depends(sql_db.get_db) # producer: ProducerCreate, db: Session = Depends(sql_db.get_db)
) -> Producer: # ) -> Producer:
# # todo checken ob schon da ...
# return sql_crud.create_producer(db=db, producer=producer)
@router.post("/api/v1/create_entity", response_model=Entity, tags=[Tags.entities])
def create_entity(
entity: EntityCreate, db: Session = Depends(sql_db.get_db)
) -> EntityCreate:
# todo checken ob schon da ... # todo checken ob schon da ...
return sql_crud.create_producer(db=db, producer=producer) return sql_crud.create_entity(db, entity)
@router.get("/api/v1/get_entities", response_model=List[Entity], tags=[Tags.entities])
def get_entities(
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
) -> List[sql_models.Entity]:
entities = sql_crud.get_entities(db, skip=skip, limit=limit)
return entities

View File

@@ -14,6 +14,23 @@ class Machine(BaseModel):
status: Status status: Status
class EntityBase(BaseModel):
did: str = "did:sov:test:1234"
name: str = "C1"
ip: str = "127.0.0.1"
attached: bool = False
other: dict = {"test": "test"}
class Entity(EntityBase):
class Config:
orm_mode = True
class EntityCreate(EntityBase):
pass
class RepositoryBase(BaseModel): class RepositoryBase(BaseModel):
title: str title: str
description: str | None = None description: str | None = None

View File

@@ -2,37 +2,51 @@ from typing import List
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from . import api_outputs, sql_models from . import schemas, sql_models
def get_producers( def create_entity(db: Session, entity: schemas.EntityCreate) -> sql_models.Entity:
db: Session, skip: int = 0, limit: int = 100 db_entity = sql_models.Entity(**entity.dict())
) -> List[sql_models.Producer]: db.add(db_entity)
return db.query(sql_models.Producer).offset(skip).limit(limit).all()
def create_producer(
db: Session, producer: api_outputs.ProducerCreate
) -> sql_models.Producer:
jsonblob_init = {"test_repo": "jsonblob_create"}
db_producer = sql_models.Producer(jsonblob=jsonblob_init)
db.add(db_producer)
db.commit() db.commit()
db.refresh(db_producer) db.refresh(db_entity)
return db_producer return db_entity
def get_repositories( def get_entities(
db: Session, skip: int = 0, limit: int = 100 db: Session, skip: int = 0, limit: int = 100
) -> List[sql_models.Repository]: ) -> List[sql_models.Entity]:
return db.query(sql_models.Repository).offset(skip).limit(limit).all() return db.query(sql_models.Entity).offset(skip).limit(limit).all()
def create_repository( # def get_producers(
db: Session, repository: api_outputs.RepositoryCreate, producers_id: int # db: Session, skip: int = 0, limit: int = 100
) -> sql_models.Repository: # ) -> List[sql_models.Producer]:
db_repository = sql_models.Repository(**repository.dict(), prod_id=producers_id) # return db.query(sql_models.Producer).offset(skip).limit(limit).all()
db.add(db_repository)
db.commit()
db.refresh(db_repository) # def create_producer(
return db_repository # db: Session, producer: schemas.ProducerCreate
# ) -> sql_models.Producer:
# jsonblob_init = {"test_repo": "jsonblob_create"}
# db_producer = sql_models.Producer(jsonblob=jsonblob_init)
# db.add(db_producer)
# db.commit()
# db.refresh(db_producer)
# return db_producer
# def get_repositories(
# db: Session, skip: int = 0, limit: int = 100
# ) -> List[sql_models.Repository]:
# return db.query(sql_models.Repository).offset(skip).limit(limit).all()
# def create_repository(
# db: Session, repository: schemas.RepositoryCreate, producers_id: int
# ) -> sql_models.Repository:
# db_repository = sql_models.Repository(**repository.dict(), prod_id=producers_id)
# db.add(db_repository)
# db.commit()
# db.refresh(db_repository)
# return db_repository

View File

@@ -1,23 +1,90 @@
from sqlalchemy import JSON, Column, ForeignKey, Integer from sqlalchemy import JSON, Boolean, Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from .sql_db import Base from .sql_db import Base
# Relationsship example
# https://dev.to/freddiemazzilli/flask-sqlalchemy-relationships-exploring-relationship-associations-igo
class Producer(Base):
class Entity(Base):
__tablename__ = "entities"
## Queryable body ##
did = Column(String, primary_key=True, index=True)
name = Column(String, index=True)
ip = Column(String, index=True)
attached = Column(Boolean, index=True)
## Non queryable body ##
# In here we deposit: Network, Roles, Visible, etc.
other = Column(JSON)
## Relations ##
producers = relationship("Producer", back_populates="entity")
consumers = relationship("Consumer", back_populates="entity")
# repository = relationship("Repository", uselist=False, back_populates="entity")
class ProducerAbstract(Base):
__abstract__ = True
# Queryable body
id = Column(Integer, primary_key=True, index=True)
service_name = Column(String, unique=True, index=True)
service_type = Column(String, index=True)
endpoint_url = Column(String, index=True)
status = Column(String, index=True)
## Non queryable body ##
# In here we deposit: Action
other = Column(JSON)
class Producer(ProducerAbstract):
__tablename__ = "producers" __tablename__ = "producers"
# Usage is the consumers column
## Relations ##
# One entity can have many producers
entity = relationship("Entity", back_populates="producers")
entity_did = Column(Integer, ForeignKey("entities.did"))
# One producer has many consumers
consumers = relationship("Consumer", back_populates="producer")
class Consumer(Base):
__tablename__ = "consumers"
## Queryable body ##
id = Column(Integer, primary_key=True, index=True) id = Column(Integer, primary_key=True, index=True)
jsonblob = Column(JSON)
repos = relationship("Repository", back_populates="producer") ## Relations ##
# one entity can have many consumers
entity = relationship("Entity", back_populates="consumers")
entity_did = Column(Integer, ForeignKey("entities.did"))
# one consumer has one producer
producer = relationship("Producer", back_populates="consumers")
producer_id = Column(Integer, ForeignKey("producers.id"))
class Repository(Base): # class Repository(ProducerAbstract):
__tablename__ = "repositories" # __tablename__ = "repositories"
id = Column(Integer, primary_key=True, index=True) # # one repository has one entity
jsonblob = Column(JSON) # entity = relationship("Entity", back_populates="repository")
prod_id = Column(Integer, ForeignKey("producers.id")) # entity_did = Column(Integer, ForeignKey("entities.did"))
producer = relationship("Producer", back_populates="repos")
# TODO: Ask how this works exactly
class Resolution(Base):
__tablename__ = "resolutions"
id = Column(Integer, primary_key=True)
requester_name = Column(String, index=True)
requester_did = Column(String, index=True)
resolved_did = Column(String, index=True)
timestamp = Column(DateTime, index=True)

View File

@@ -0,0 +1,32 @@
from enum import Enum
from typing import Any, Dict, List
class Tags(Enum):
producers = "producers"
consumers = "consumers"
entities = "entities"
repositories = "repositories"
def __str__(self) -> str:
return self.value
tags_metadata: List[Dict[str, Any]] = [
{
"name": str(Tags.producers),
"description": "Operations on a producer.",
},
{
"name": str(Tags.consumers),
"description": "Operations on a consumer.",
},
{
"name": str(Tags.entities),
"description": "Operations on an entity.",
},
{
"name": str(Tags.repositories),
"description": "Operations on a repository.",
},
]