Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

details = "Exception calling application: 'BlogProtoSerializer' object has no attribute 'proto_class'" #45

Open
JonesThePotato opened this issue Jun 18, 2023 · 7 comments

Comments

@JonesThePotato
Copy link

I checked everything and followed every step of the document. Got as much as help from AIs too, no progress. I'll share any code if necessary.

@AMontagu
Copy link

You forgot to add one line in your serializers. See: https://djangogrpcframework.readthedocs.io/en/latest/quickstart.html#writing-serializers

For information this repo is no more maintained. If you are at the start of your projet considere looking at: https://github.com/socotecio/django-socio-grpc/

@JonesThePotato
Copy link
Author

from django_grpc_framework.proto_serializers import ModelProtoSerializer
from django_grpc_framework import proto_serializers
from .models import Blog, Tag, Category, ImageModel
import blog_pb2 as blog_pb2 


class ImageModelProtoSerializer(proto_serializers.ModelProtoSerializer):
    class Meta:
        model = ImageModel
        proto_class = blog_pb2.ImageModel
        fields = ('id', 'content_photo',)
        read_only_fields = ('id',)


class TagProtoSerializer(proto_serializers.ModelProtoSerializer):
    class Meta:
        model = Tag
        proto_class = blog_pb2.Tag
        fields = ('id', 'title', 'description',)
        read_only_fields = ('id',)


class CategoryProtoSerializer(proto_serializers.ModelProtoSerializer):
    class Meta:
        model = Category
        proto_class = blog_pb2.Category
        fields = ('id', 'title', 'description', 'photo',)
        read_only_fields = ('id',)


class BlogProtoSerializer(proto_serializers.ModelProtoSerializer):
    image_models = ImageModelProtoSerializer(many=True, required=False)

    class Meta:
        model = Blog
        proto_class = blog_pb2.Blog
        fields = ('id', 'author', 'created_at', 'updated_at', 'tag', 'category', 'title', 'main_photo', 'content_photo', 'like', 'comment', 'image_models',)
        read_only_fields = ('id', 'created_at', 'updated_at', 'like', 'comment',)
        write_only_fields = ('main_photo',)

    def to_proto(self, instance):
        proto = self.proto_class(
            id=instance.id,
            author=instance.author,
            created_at=instance.created_at,
            updated_at=instance.updated_at,
            tag=instance.tag,
            category=instance.category,
            title=instance.title,
            main_photo=instance.main_photo,
            content_photo=instance.content_photo,
            like=instance.like,
            comment=instance.comment,
            image_models=[self.image_models.to_proto(image) for image in instance.image_models],
        )
        return proto

I checked. Everything is how it's supposed to be.

@AMontagu
Copy link

def to_proto(self, instance):
        proto = self.proto_class(
            id=instance.id,
            author=instance.author,
            created_at=instance.created_at,
            updated_at=instance.updated_at,
            tag=instance.tag,
            category=instance.category,
            title=instance.title,
            main_photo=instance.main_photo,
            content_photo=instance.content_photo,
            like=instance.like,
            comment=instance.comment,
            image_models=[self.image_models.to_proto(image) for image in instance.image_models],
        )
        return proto

You call self.proto_class but it should be self.Meta.proto_class.

@JonesThePotato
Copy link
Author

Thank you for your insight. Now I am running into another error. No idea where to look at.
PS : Thank you so much for your responds! I have been stuck for few weeks.
Error : PS C:\Users\JonseThePotato\Documents\Work\microservices> py coresystem.py

  1. List All Blogs
  2. View a Blog
  3. Create a Blog
  4. Update a Blog
  5. Delete a Blog
  6. Quit
    Enter your choice (1-6): 1
    Traceback (most recent call last):
    File "C:\Users\JonseThePotato\Documents\Work\microservices\coresystem.py", line 99, in
    run()
    File "C:\Users\JonseThePotato\Documents\Work\microservices\coresystem.py", line 36, in run
    list_blogs(stub)
    File "C:\Users\JonseThePotato\Documents\Work\microservices\coresystem.py", line 52, in list_blogs
    response = stub.List(list_request)
    ^^^^^^^^^^^^^^^^^^^^^^^
    File "C:\Program Files\Python311\Lib\site-packages\grpc_channel.py", line 1030, in call
    return _end_unary_response_blocking(state, call, False, None)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "C:\Program Files\Python311\Lib\site-packages\grpc_channel.py", line 910, in _end_unary_response_blocking
    raise _InactiveRpcError(state) # pytype: disable=not-instantiable
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNKNOWN
    details = "Exception calling application: Message must be initialized with a dict: blog.Blog"
    debug_error_string = "UNKNOWN:Error received from peer {created_time:"2023-06-19T16:59:52.950338936+00:00", grpc_status:2, grpc_message:"Exception calling application: Message must be initialized with a dict: blog.Blog"}"

blog.proto :```
syntax = "proto3";

package blog;

import "google/protobuf/timestamp.proto";

message ImageModel {
string content_photo = 1;
}

message Tag {
int32 id = 1;
string title = 2;
string description = 3;
}

message Category {
int32 id = 1;
string title = 2;
string description = 3;
string photo = 4;
}

message Blog {
int32 id = 1;
string author = 2;
google.protobuf.Timestamp created_at = 3;
google.protobuf.Timestamp updated_at = 4;
Tag tag = 5;
Category category = 6;
string title = 7;
string main_photo = 8;
repeated ImageModel content_photo = 9;
int32 like = 10;
string comment = 11;
int32 category_id = 12;
int32 tag_id = 13;
}

// Request and Response messages for your gRPC service methods
message BlogListRequest {
// ...
}

message BlogListResponse {
repeated Blog blogs = 1;
}

// ... Add other request and response messages for Retrieve, Create, Update, and Delete methods

// Retrieve
message BlogRetrieveRequest {
int32 id = 1;
}

message BlogRetrieveResponse {
Blog blog = 1;
}

// Create
message BlogCreateRequest {
Blog blog = 1;
}

message BlogCreateResponse {
Blog blog = 1;
}

// Update
message BlogUpdateRequest {
int32 id = 1;
Blog blog = 2;
}

message BlogUpdateResponse {
Blog blog = 1;
}

// Delete
message BlogDeleteRequest {
int32 id = 1;
}

message BlogDeleteResponse {
bool success = 1;
}

service BlogService {
rpc List (BlogListRequest) returns (BlogListResponse);
rpc Retrieve (BlogRetrieveRequest) returns (BlogRetrieveResponse);
rpc Create (BlogCreateRequest) returns (BlogCreateResponse);
rpc Update (BlogUpdateRequest) returns (BlogUpdateResponse);
rpc Delete (BlogDeleteRequest) returns (BlogDeleteResponse);
}



services.py : ```
import grpc
import blog_pb2 as blog_pb2
import blog_pb2_grpc as blog_pb2_grpc
from django.shortcuts import get_object_or_404
from django_grpc_framework.services import Service
from blog.serializers import BlogProtoSerializer 
from .models import Blog


class BlogService(blog_pb2_grpc.BlogServiceServicer):
    def List(self, request, context):
        blogs = Blog.objects.all()
        serializer = BlogProtoSerializer()  # Instantiate the serializer
        blog_protos = [serializer.to_proto(blog) for blog in blogs]
        return blog_pb2.BlogListResponse(blogs=blog_protos)

    def Retrieve(self, request, context):
        blog = get_object_or_404(Blog, id=request.id)
        serializer = BlogProtoSerializer()  # Instantiate the serializer
        blog_proto = serializer.to_proto(blog)
        return blog_proto

    def Create(self, request, context):
        serializer = BlogProtoSerializer()  # Instantiate the serializer
        blog = serializer.create(request)
        blog.save()
        blog_proto = serializer.to_proto(blog)
        return blog_proto

    def Update(self, request, context):
        blog = get_object_or_404(Blog, id=request.id)
        serializer = BlogProtoSerializer()  # Instantiate the serializer
        updated_blog = serializer.update(blog, request)
        updated_blog.save()
        blog_proto = serializer.to_proto(updated_blog)
        return blog_proto

    def Delete(self, request, context):
        blog = get_object_or_404(Blog, id=request.id)
        blog.delete()
        return blog_pb2.Empty()

handlers.py : ```
from blog.services import BlogService
import blog_pb2_grpc

def grpc_handlers(server):
"""
Register the BlogService with the gRPC server.
"""
blog_pb2_grpc.add_BlogServiceServicer_to_server(BlogService(), server)



client.py : ```
import logging
import os
import sys
import grpc
import django
from django.conf import settings
from django.shortcuts import get_object_or_404
from django_grpc_framework.services import Service
sys.path.append('c:/Users/JonseThePotato/Documents/Work/MicroServices/BlogSystem/BlogSystem')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'BlogSystem.settings')
django.setup()
from blog.serializers import BlogProtoSerializer
from blog.models import Blog
import blog_pb2_grpc
import blog_pb2

logging.basicConfig(level=logging.INFO)



def run():
    channel = grpc.insecure_channel('localhost:50051')
    stub = blog_pb2_grpc.BlogServiceStub(channel)

    while True:
        print("1. List All Blogs")
        print("2. View a Blog")
        print("3. Create a Blog")
        print("4. Update a Blog")
        print("5. Delete a Blog")
        print("6. Quit")

        choice = input("Enter your choice (1-6): ")
        
        if choice == '1':
            list_blogs(stub)
        elif choice == '2':
            retrieve_blog(stub)
        elif choice == '3':
            create_blog(stub)
        elif choice == '4':
            update_blog(stub)
        elif choice == '5':
            delete_blog(stub)
        elif choice == '6':
            break
        else:
            print("Invalid choice. Please try again.")

def list_blogs(stub):
    list_request = blog_pb2.BlogListRequest()
    response = stub.List(list_request)
    
    print("Blogs:")
    for blog in response.blogs:
        print(f"ID: {blog.id}, Title: {blog.title}, Content: {blog.content}")
    print()

def retrieve_blog(stub):
    blog_id = input("Enter the ID of the blog: ")
    retrieve_request = blog_pb2.BlogRetrieveRequest(id=int(blog_id))
    response = stub.Retrieve(retrieve_request)

    print(f"Blog - ID: {response.id}, Title: {response.title}, Content: {response.content}")
    print()

def create_blog(stub):
    title = input("Enter the title of the blog: ")
    content = input("Enter the content of the blog: ")
    blog = blog_pb2.Blog(title=title, main_photo=content)  
    create_request = blog_pb2.BlogCreateRequest(blog=blog)  
    response = stub.Create(create_request)

    print(f"Created Blog - ID: {response.blog.id}, Title: {response.blog.title}, Content: {response.blog.main_photo}")
    print()


def update_blog(stub):
    blog_id = input("Enter the ID of the blog to update: ")
    title = input("Enter the new title of the blog: ")
    content = input("Enter the new content of the blog: ")
    blog = blog_pb2.Blog(id=int(blog_id), title=title, main_photo=content)  
    update_request = blog_pb2.BlogUpdateRequest(id=int(blog_id), blog=blog)  
    response = stub.Update(update_request)

    print(f"Updated Blog - ID: {response.blog.id}, Title: {response.blog.title}, Content: {response.blog.main_photo}")
    print()


def delete_blog(stub):
    blog_id = input("Enter the ID of the blog to delete: ")
    delete_request = blog_pb2.BlogDeleteRequest(id=int(blog_id))
    response = stub.Delete(delete_request)

    print("Blog deleted successfully.")
    print()

if __name__ == '__main__':
    run()

@AMontagu
Copy link

As I said in my first message: For information this repo is no more maintained. If you are at the start of your projet considere looking at: https://github.com/socotecio/django-socio-grpc/

It look like you are doing a small school project.
Django is a web framework mostly used for website not CMD program.
Have you considered not using django and gRPC and just basic python to learn ? Or it it specific to learn gRPC ?

@JonesThePotato
Copy link
Author

I just started working at a company and still learning. This is a small part I was trusted with. I was told to do what I am doing right now. I must use this framework.

@JonesThePotato
Copy link
Author

I would really appreciate it if you could guide me through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants