10:56 am

PragetX

PPP

Frontend CD Github Action

SetUp and Updated CI/CD Pipeline in new github repo of InfinityTalks.

Following is updated github action yaml file It’s Yarn with vite.

name: Deploy React App to EC2
 
on:
  push:
    branches:
      - main # Change this to the branch you want to deploy from
 
jobs:
  build:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
 
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '21' # Change this to match your project's Node.js version
 
      - name: Install dependencies
        run: yarn install
 
      - name: Build React app
        run: CI=false yarn build
 
      - name: SSH into EC2 instance and delete previous files
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
          port: 22 # Change if your SSH port is different
          script: |
            [ -d "/tmp/dist/" ] && sudo rm -rf "/tmp/dist/"/*
            [ -d "/var/www/html/" ] && sudo rm -rf "/var/www/html/"/*
      
      - name: SCP to EC2 instance
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
          source: "dist/" # Change this to match your build output directory
          target: "/tmp" # Change this to a directory accessible by the SSH user on the EC2 instance
 
      - name: SSH into EC2 instance and deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
          port: 22 # Change if your SSH port is different
          script: |
            sudo mv /tmp/dist/* /var/www/html/
            sudo systemctl reload nginx
 

Were errors in Typescript Frontend: Solved Dependency issues, By updating packages Solved an error of non accesible variable

Solved Unused vars errors And minor contact name change

Backend

  • Updated APIs for Create and Bulk Update
class DesignationPagePermissionCreateUpdateSerializer(serializers.ModelSerializer):
	pages = serializers.ListField(child=PagePermissionUpdateSerializer())
 
    class Meta:
        model = Designation
        fields = ["designation_name", "description", "is_active", "pages"]
 
    def create(self, validated_data):
        pages_data = validated_data.pop("pages", [])
        designation = Designation.objects.create(**validated_data)
        for page_data in pages_data:
            page = Page.objects.get(id=page_data["id"])
 
            permission_data = page_data["permission"]
            permission_data["route"] = page.id
            permission_data["designation"] = designation.id
            permission = PermissionCreateUpdateSerializer(data=permission_data)
            if permission.is_valid():
                permission.save()
            else:
                raise serializers.ValidationError(permission.errors)
        instance = DesignationPagePermissionSerializer(designation).data
        return instance
 
    def update(self, instance, validated_data):
        pages_data = validated_data.pop("pages", [])
        super().update(instance, validated_data)
        for page_data in pages_data:
            page = page_data["id"]
            original_permission = Permission.objects.filter(
		# ...
 
            if updated_permission.is_valid():
                updated_permission.save()
            else:
                raise serializers.ValidationError(updated_permission.errors)
	    # ...

Updated View for Same

 
class DesignationBulkPermissionApi(ModelViewSet):
	# ...
    @swagger_auto_schema(
        request_body=DesignationPagePermissionCreateUpdateSerializer,
        operation_description="Designation Bulk Permission",
    )
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            created_designation = serializer.create(serializer.data)
            response = {
                "message": "Permission Created",
                "data": created_designation,
                "status": status.HTTP_201_CREATED,
            }
            return Response(response, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Added a Route Permission API for Current User

Since Only Retrieval was required. Simply implemented APIView

class RoutePermission(APIView):
    @swagger_auto_schema(
        # request_body=DesignationPagePermissionSerializer,
        operation_description="Designation Bulk Permission",
    )
    def get(self, request, *args, **kwargs):
        designation_obj = request.user.designation
        if not designation_obj:
            return Response(
                {
                    "message": "Designation not found",
                    "status": False,
                },
                status=status.HTTP_400_BAD_REQUEST,
            )
 
        route_id = kwargs.get("id")
        route_obj = Page.objects.get(id=route_id)
        permisson_obj = Permission.objects.filter(
            designation=designation_obj.id, route=route_obj
        ).last()
        response = {
            "data": CustomPermissionUpdateSerializer(permisson_obj).data,
            "status": status.HTTP_200_OK,
        }
        return Response(response, status=status.HTTP_200_OK)

InfinityTalks

Implemented CRUD for Ratings

Serializer

class ListenerRatingSerializer(serializers.ModelSerializer):
    class Meta:
        model = ListenerRating
        fields = "__all__"

Viewset

class ListenerRatingApi(CustomViewSetMaster):
    serializer_class = ListenerRatingSerializer
 
    def get_queryset(self, request):
        queryset = ListenerRating.objects.all()
        return queryset
Ratings Stats in ListenerDetailsAPI.

Wasn’t implemented at all. Code existed with no basis.

Updated code. And optimized to make less db request.

Connection Prematurely closed Issue.

Researched why that can happen Found a solution roughly. “upstream prematurely closed connection while reading response header from upstream” Django, Ubuntu, Nginx, Gunicorn Default timeout of Gunicorn is 30s. Setting higher timout in Nginx and Gunicorn can solve this. Probably.

ExecStart=/home/ubuntu/yourworkspace/venvProject/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/yourworkspace/Project/app.sock  --timeout 600  -m 007 wsgi:app
location / {
        include proxy_params;
       proxy_read_timeout 600s;
       proxy_connect_timeout 600s;
      proxy_pass http://unix:/home/ubuntu/yourworkspace/Project/app.sock;
        }

<<Yesterday Tomorrow>>


Links : Tags : Year : 2024 Month : March 24, March Date : 14th March, Thursday, 2024, 14th March Category : Daily