diff --git a/Makefile b/Makefile
index ae53886..9a73ad1 100644
--- a/Makefile
+++ b/Makefile
@@ -133,9 +133,6 @@ run-pgadmin:
echo "$$SERVERS_JSON" > ./pgadmin/servers.json && \
docker volume create pgadmin_data && \
docker compose -f pgadmin.yml up --force-recreate
-
-load-server-pgadmin:
- docker exec -it pgadmin python /pgadmin4/setup.py --load-servers servers.json
clean-pgadmin:
docker volume rm pgadmin_data
diff --git a/README.md b/README.md
index d627434..e042394 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Developing web applications can be a challenging process, especially when dealin
- Development Best Practices: We apply code formatting, type checking, and static analysis tools to ensure that the code is readable, robust, and reliable.
## Table of Contents
-1. [Set environment variables](#set-environment-variables)
+1. [Prerequisites](#prerequisites)
2. [Run the project using Docker containers and forcing build containers](#run-the-project-using-docker-containers-and-forcing-build-containers)
3. [Run project using Docker containers](#run-project-using-docker-containers)
4. [Setup database with initial data](#setup-database-with-initial-data)
@@ -36,10 +36,72 @@ Developing web applications can be a challenging process, especially when dealin
20. [TODO List](#todo-list)
21. [License](#license)
+# Prerequisites
+
## Set environment variables
Create an **.env** file on root folder and copy the content from **.env.example**. Feel free to change it according to your own configuration.
+## Docker engine
+This project utilizes Docker and Docker Compose, so please ensure that you have installed the latest version compatible with your operating system. If you haven't already installed Docker, you can find detailed instructions on how to do so [here](https://docs.docker.com/engine/install/). Docker desktop can be good for a dev computer.
+
+You can check if it is installed with this command
+```
+docker --version
+```
+
+## Make
+"Make" is a build automation tool that is primarily used to manage the compilation and building of software projects. It reads a file called a "Makefile" which specifies a set of rules and dependencies for building a project, and then executes the necessary commands to build the project according to those rules. Depending of your OS you will requiere to install it in different ways.
+
+Mac
+```
+xcode-select --install
+```
+
+Ubuntu
+```
+sudo apt-get install build-essential
+sudo apt-get -y install make
+```
+
+You can check if it is installed with this command
+```
+make --version
+```
+
+## Python ">3.9,<3.12"
+If you haven't already installed Python. You can download and install python from [here](https://www.python.org/downloads/).
+
+You can check yu python version:
+```
+python --version
+```
+
+## Poetry
+
+Python Poetry is a tool for dependency management and packaging in Python. It provides a modern and efficient approach to managing Python projects' dependencies, virtual environments, and packaging. You can find detailed instructions on how install it [here](https://python-poetry.org/docs/#installing-with-the-official-installer). Poetry manages packages in **pyproject.toml** file; In this project you can find it in the folder backend/app.
+
+You can check if it is installed with this command
+```
+poetry --version
+```
+
+### Dev tip to activate virtual environment
+When you are opening python files do this cna help you to vscode detect installed packages.
+
+```
+cd backend/app/
+poetry shell
+```
+
+After that you can show the interpreted path. You can copy that path and set as the default for the project in vscode. Press on **Enter interpreter path ..** and past path.
+
+
+
+
+
+
+
## Run the project using Docker containers and forcing build containers
*Using docker compose command*
@@ -92,12 +154,7 @@ You can connect to the Database using pgAdmin4 and use the credentials from .env
make run-pgadmin
```
-*Load server configuration (It is required just the first time)*
-```sh
-make load-server-pgadmin
-```
-
-This starts pgamin in [http://localhost:15432](http://localhost:15432).
+This starts pgamin in [http://localhost:15432](http://localhost:15432). When connecting to db server introduce the password by default it is **postgres** if you didn't change it in .env file.
@@ -298,13 +355,13 @@ make mypy
```
## Basic chatbot example with Langchain and OpenAI
-In addition to its core features, this project template demonstrates how to integrate an basic chatbot powered by Langchain and OpenAI through websockets.
+In addition to its core features, this project template demonstrates how to integrate an basic chatbot powered by Langchain and OpenAI through websockets. You can use [PieSocket Websocket Tester](https://chromewebstore.google.com/detail/oilioclnckkoijghdniegedkbocfpnip) to test websockets.
To begin experimenting with the basic chatbot, follow these steps:
1. **Obtain an OpenAI API Key**: You'll need to set the `OPENAI_API_KEY` environment variable, which you can obtain from [OpenAI's platform](https://platform.openai.com/).
-2. **Test Websocket Connection**: You can test the websocket connection by using the following URL: [ws://fastapi.localhost/chat/\](ws://fastapi.localhost/chat/). Replace `` with a user identifier of your choice.
+2. **Test Websocket Connection**: You can test the websocket connection by using the following URL: [ws://fastapi.localhost/chat/\](ws://fastapi.localhost/chat/). Replace `` with a user identifier of your choice. It should be the ID of your user.
3. **Sending and Receiving Messages**: You should be able to send messages to the chatbot using the provided websocket connection. To do this, use the following message structure:
@@ -313,6 +370,9 @@ To begin experimenting with the basic chatbot, follow these steps:
```
Once you send a message, the chatbot will respond with generated responses based on the content of your input.
+
+
+
## Inspiration and References
diff --git a/backend/app/app/api/v1/endpoints/login.py b/backend/app/app/api/v1/endpoints/login.py
index 07a3968..126bee5 100644
--- a/backend/app/app/api/v1/endpoints/login.py
+++ b/backend/app/app/api/v1/endpoints/login.py
@@ -158,7 +158,7 @@ async def get_new_access_token(
status_code=status.HTTP_403_FORBIDDEN,
detail="Error when decoding the token. Please check your request.",
)
- except MissingRequiredClaimError as e:
+ except MissingRequiredClaimError:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="There is no required field in your token. Please contact the administrator.",
diff --git a/backend/app/app/crud/base_crud.py b/backend/app/app/crud/base_crud.py
index 993771a..8f13c80 100644
--- a/backend/app/app/crud/base_crud.py
+++ b/backend/app/app/crud/base_crud.py
@@ -85,7 +85,7 @@ async def get_multi_paginated(
db_session = db_session or self.db.session
if query is None:
query = select(self.model)
-
+
output = await paginate(db_session, query, params)
return output
diff --git a/backend/app/app/db/session.py b/backend/app/app/db/session.py
index 2f70633..14cdc28 100644
--- a/backend/app/app/db/session.py
+++ b/backend/app/app/db/session.py
@@ -34,8 +34,8 @@
str(settings.ASYNC_CELERY_BEAT_DATABASE_URI),
# echo=True,
future=True,
- #pool_size=POOL_SIZE,
- #max_overflow=64,
+ # pool_size=POOL_SIZE,
+ # max_overflow=64,
)
SessionLocalCelery = sessionmaker(
diff --git a/backend/app/app/main.py b/backend/app/app/main.py
index 3c3c0a5..c178806 100644
--- a/backend/app/app/main.py
+++ b/backend/app/app/main.py
@@ -17,7 +17,6 @@
from fastapi_cache.backends.redis import RedisBackend
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import WebSocketRateLimiter
-from fastapi_pagination import add_pagination
from jwt import DecodeError, ExpiredSignatureError, MissingRequiredClaimError
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage
@@ -189,7 +188,7 @@ async def websocket_endpoint(websocket: WebSocket, user_id: UUID):
# Receive and send back the client message
data = await websocket.receive_json()
await ws_ratelimit(websocket)
- user_message = IUserMessage.parse_obj(data)
+ user_message = IUserMessage.model_validate(data)
user_message.user_id = user_id
resp = IChatResponse(
@@ -227,7 +226,7 @@ async def websocket_endpoint(websocket: WebSocket, user_id: UUID):
message_id="",
id="",
sender="bot",
- message="Sorry, something went wrong. Your user limit of api usages has been reached.",
+ message="Sorry, something went wrong. Your user limit of api usages has been reached or check your API key.",
type="error",
)
await websocket.send_json(resp.dict())
@@ -237,4 +236,4 @@ async def websocket_endpoint(websocket: WebSocket, user_id: UUID):
# Add Routers
-app.include_router(api_router_v1, prefix=settings.API_V1_STR)
\ No newline at end of file
+app.include_router(api_router_v1, prefix=settings.API_V1_STR)
diff --git a/backend/app/app/models/base_uuid_model.py b/backend/app/app/models/base_uuid_model.py
index 3fc4838..d7e89cf 100644
--- a/backend/app/app/models/base_uuid_model.py
+++ b/backend/app/app/models/base_uuid_model.py
@@ -4,6 +4,7 @@
from sqlalchemy.orm import declared_attr
from datetime import datetime
+
# id: implements proposal uuid7 draft4
class SQLModel(_SQLModel):
@declared_attr # type: ignore
diff --git a/backend/app/app/models/team_model.py b/backend/app/app/models/team_model.py
index a6fd909..cb0f727 100644
--- a/backend/app/app/models/team_model.py
+++ b/backend/app/app/models/team_model.py
@@ -4,7 +4,6 @@
from uuid import UUID
-
class TeamBase(SQLModel):
name: str = Field(index=True)
headquarters: str
diff --git a/backend/app/app/models/user_follow_model.py b/backend/app/app/models/user_follow_model.py
index e1f5225..2f9f3f4 100644
--- a/backend/app/app/models/user_follow_model.py
+++ b/backend/app/app/models/user_follow_model.py
@@ -10,4 +10,6 @@ class UserFollowBase(SQLModel):
class UserFollow(BaseUUIDModel, UserFollowBase, table=True):
- is_mutual: bool | None = Field(default=None, sa_column=Column(Boolean(), server_default="0"))
+ is_mutual: bool | None = Field(
+ default=None, sa_column=Column(Boolean(), server_default="0")
+ )
diff --git a/backend/app/app/schemas/common_schema.py b/backend/app/app/schemas/common_schema.py
index 2267106..487ae3d 100644
--- a/backend/app/app/schemas/common_schema.py
+++ b/backend/app/app/schemas/common_schema.py
@@ -28,7 +28,7 @@ class TokenType(str, Enum):
class IUserMessage(BaseModel):
"""User message schema."""
- user_id: UUID | None
+ user_id: UUID | None = None
message: str
diff --git a/backend/app/app/schemas/hero_schema.py b/backend/app/app/schemas/hero_schema.py
index 7ddfe97..0878e6f 100644
--- a/backend/app/app/schemas/hero_schema.py
+++ b/backend/app/app/schemas/hero_schema.py
@@ -6,7 +6,7 @@
class IHeroCreate(HeroBase):
- @field_validator('age')
+ @field_validator("age")
def check_age(cls, value):
if value < 0:
raise ValueError("Invalid age")
diff --git a/backend/app/app/schemas/image_media_schema.py b/backend/app/app/schemas/image_media_schema.py
index d20c96e..61382d0 100644
--- a/backend/app/app/schemas/image_media_schema.py
+++ b/backend/app/app/schemas/image_media_schema.py
@@ -1,6 +1,6 @@
from app.models.image_media_model import ImageMedia, ImageMediaBase
from app.models.media_model import Media
-from pydantic import model_validator, root_validator
+from pydantic import model_validator
from .media_schema import IMediaRead
from app.utils.partial import optional
@@ -20,11 +20,11 @@ class IImageMediaRead(ImageMediaBase):
media: IMediaRead | None
-#Todo make it compatible with pydantic v2
+# Todo make it compatible with pydantic v2
class IImageMediaReadCombined(ImageMediaBase):
link: str | None
- @model_validator(mode='before')
+ @model_validator(mode="before")
def combine_attributes(cls, values):
link_fields = {"link": values.get("link", None)}
if "media" in values:
diff --git a/backend/app/app/schemas/team_schema.py b/backend/app/app/schemas/team_schema.py
index eb78ba5..968abfd 100644
--- a/backend/app/app/schemas/team_schema.py
+++ b/backend/app/app/schemas/team_schema.py
@@ -1,4 +1,3 @@
-from typing import Any
from app.models.hero_model import HeroBase
from app.models.team_model import TeamBase
from .user_schema import IUserBasicInfo
diff --git a/backend/app/app/schemas/user_schema.py b/backend/app/app/schemas/user_schema.py
index 7c1710d..47038b0 100644
--- a/backend/app/app/schemas/user_schema.py
+++ b/backend/app/app/schemas/user_schema.py
@@ -4,7 +4,7 @@
from pydantic import BaseModel
from uuid import UUID
from enum import Enum
-from .image_media_schema import IImageMediaReadCombined, IImageMediaRead
+from .image_media_schema import IImageMediaRead
from .role_schema import IRoleRead
diff --git a/backend/app/app/utils/partial.py b/backend/app/app/utils/partial.py
index f0054d4..b703a0d 100644
--- a/backend/app/app/utils/partial.py
+++ b/backend/app/app/utils/partial.py
@@ -2,7 +2,6 @@
# https://github.com/pydantic/pydantic/pull/3179
# https://github.com/pydantic/pydantic/issues/1673
-from pydantic import BaseModel
from copy import deepcopy
from typing import Any, Callable, Optional, Type, TypeVar
from pydantic import BaseModel, create_model
diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml
index d6d9822..64bd660 100644
--- a/docker-compose-dev.yml
+++ b/docker-compose-dev.yml
@@ -18,23 +18,22 @@ services:
- caddy_reverse_proxy:storage.localhost
database:
- image: bitnami/postgresql:13.3.0
+ image: bitnami/postgresql
restart: always
container_name: database
env_file: ".env"
user: root
volumes:
- - ./db_docker:/bitnami/postgresql
+ - db_docker:/bitnami/postgresql
- ./create-dbs.sql:/docker-entrypoint-initdb.d/create-dbs.sql
ports:
- 5454:5432 # Remove this on production
expose:
- 5432
environment:
- - POSTGRES_USERNAME=${DATABASE_USER}
- - POSTGRES_PASSWORD=${DATABASE_PASSWORD}
- - POSTGRES_DATABASE=${DATABASE_NAME}
- - POSTGRES_HOST_AUTH_METHOD= "trust"
+ - POSTGRESQL_USERNAME=${DATABASE_USER}
+ - POSTGRESQL_PASSWORD=${DATABASE_PASSWORD}
+ - POSTGRESQL_DATABASE=${DATABASE_NAME}
redis_server:
image: redis:alpine
@@ -108,5 +107,6 @@ services:
- caddy_config:/config
volumes:
+ db_docker:
caddy_data:
caddy_config:
\ No newline at end of file
diff --git a/docker-compose-sonarqube.yml b/docker-compose-sonarqube.yml
index 0b9a83b..14e7954 100644
--- a/docker-compose-sonarqube.yml
+++ b/docker-compose-sonarqube.yml
@@ -3,7 +3,7 @@ version: "3.9"
services:
sonarqube:
container_name: "sonarqube"
- image: "sonarqube:9.9.1-community"
+ image: "sonarqube:9.9.2-community"
volumes:
- ./sonarqube/extensions:/opt/sonarqube/extensions
- ./sonarqube/logs:/opt/sonarqube/logs
diff --git a/docker-compose-test.yml b/docker-compose-test.yml
index 1010382..688ddaa 100644
--- a/docker-compose-test.yml
+++ b/docker-compose-test.yml
@@ -22,23 +22,22 @@ services:
- caddy_reverse_proxy:storage.localhost
database:
- image: bitnami/postgresql:13.3.0
+ image: bitnami/postgresql
restart: always
container_name: database
env_file: ".env"
user: root
volumes:
- - ./db_docker:/bitnami/postgresql
+ - db_docker:/bitnami/postgresql
- ./create-dbs.sql:/docker-entrypoint-initdb.d/create-dbs.sql
ports:
- 5454:5432 # Remove this on production
expose:
- 5432
environment:
- - POSTGRES_USERNAME=${DATABASE_USER}
- - POSTGRES_PASSWORD=${DATABASE_PASSWORD}
- - POSTGRES_DATABASE=${DATABASE_NAME}
- - POSTGRES_HOST_AUTH_METHOD= "trust"
+ - POSTGRESQL_USERNAME=${DATABASE_USER}
+ - POSTGRESQL_PASSWORD=${DATABASE_PASSWORD}
+ - POSTGRESQL_DATABASE=${DATABASE_NAME}
redis_server:
image: redis:alpine
@@ -52,10 +51,7 @@ services:
container_name: celery_worker
restart: always
# platform: linux/arm64/v8
- build:
- context: ./backend
- args:
- INSTALL_DEV: "true"
+ build: ./backend
command: "watchfiles 'celery -A app.core.celery worker -l info' "
volumes:
- ./backend/app:/code
@@ -115,5 +111,6 @@ services:
- caddy_config:/config
volumes:
+ db_docker:
caddy_data:
caddy_config:
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index f3b5c34..ee37411 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -16,24 +16,24 @@ services:
links:
- caddy_reverse_proxy:storage.localhost
- database:
- image: bitnami/postgresql:13.3.0
- restart: always
- container_name: database
- env_file: ".env"
- user: root
- volumes:
- - ./db_docker:/bitnami/postgresql
- - ./create-dbs.sql:/docker-entrypoint-initdb.d/create-dbs.sql
- ports:
- - 5454:5432 # Remove this on production
- expose:
- - 5432
- environment:
- - POSTGRES_USERNAME=${DATABASE_USER}
- - POSTGRES_PASSWORD=${DATABASE_PASSWORD}
- - POSTGRES_DATABASE=${DATABASE_NAME}
- - POSTGRES_HOST_AUTH_METHOD= "trust"
+ ## You need to set your external database credentials in .env file or uncomment below lines to run database as container (No recommended because db needs persitence)
+ # database:
+ # image: bitnami/postgresql
+ # restart: always
+ # container_name: database
+ # env_file: ".env"
+ # user: root
+ # volumes:
+ # - db_docker:/bitnami/postgresql
+ # - ./create-dbs.sql:/docker-entrypoint-initdb.d/create-dbs.sql
+ # ports:
+ # - 5454:5432 # Remove this on production
+ # expose:
+ # - 5432
+ # environment:
+ # - POSTGRESQL_USERNAME=${DATABASE_USER}
+ # - POSTGRESQL_PASSWORD=${DATABASE_PASSWORD}
+ # - POSTGRESQL_DATABASE=${DATABASE_NAME}
redis_server:
diff --git a/static/python_int.png b/static/python_int.png
new file mode 100644
index 0000000..e51dcc9
Binary files /dev/null and b/static/python_int.png differ
diff --git a/static/ws.png b/static/ws.png
new file mode 100644
index 0000000..3ae715d
Binary files /dev/null and b/static/ws.png differ