Skip to content
This repository was archived by the owner on Mar 11, 2022. It is now read-only.

Commit 3a4c3b2

Browse files
authored
Merge pull request #21 from cloudstateio/feature/python-support
Merge actual state of project in Master branch
2 parents e92642a + 599765c commit 3a4c3b2

45 files changed

Lines changed: 5892 additions & 2 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
.vscode
3+
**/__pycache__/

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: python
2+
python:
3+
- "3.8"
4+
install:
5+
- pip install -r requirements.txt
6+
script: pytest

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# cloudstate_python-support
2-
Python support for CloudState
1+
# Python User Language Support
2+
Python User Language Support for [Cloudstate](https://github.com/cloudstateio/cloudstate).

build/compile-protbuf.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env bash
2+
3+
set -o nounset
4+
set -o errexit
5+
set -o pipefail
6+
7+
# follow the basic steps here: https://grpc.io/docs/tutorials/basic/python/
8+
9+
python3 -m grpc_tools.protoc -Iprotobuf/protocol --python_out=. --grpc_python_out=. protobuf/protocol/cloudstate/entity.proto
10+
python3 -m grpc_tools.protoc -Iprotobuf/protocol --python_out=. --grpc_python_out=. protobuf/protocol/cloudstate/event_sourced.proto
11+
python3 -m grpc_tools.protoc -Iprotobuf/frontend --python_out=. --grpc_python_out=. protobuf/frontend/cloudstate/entity_key.proto
12+
python3 -m grpc_tools.protoc -Iprotobuf/example/ -Iprotobuf/frontend --python_out=. --grpc_python_out=. protobuf/example/shoppingcart/shoppingcart.proto
13+
python3 -m grpc_tools.protoc -Iprotobuf/ --python_out=. --grpc_python_out=. protobuf/proxy/grpc/reflection/v1alpha/reflection.proto
14+
python3 -m grpc_tools.protoc -Iprotobuf/ --python_out=. --grpc_python_out=. protobuf/frontend/google/api/annotations.proto
15+
python3 -m grpc_tools.protoc -Iprotobuf/frontend --python_out=. --grpc_python_out=. protobuf/frontend/google/api/annotations.proto
16+
python3 -m grpc_tools.protoc -Iprotobuf/frontend --python_out=. --grpc_python_out=. protobuf/frontend/google/api/http.proto

build/fetch-cloudstate-pb.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env bash
2+
3+
set -o nounset
4+
set -o errexit
5+
set -o pipefail
6+
7+
function fetch() {
8+
local path=$1
9+
local tag=$2
10+
mkdir -p protobuf/$(dirname $path)
11+
curl -o protobuf/${path} https://raw.githubusercontent.com/cloudstateio/cloudstate/${tag}/protocols/${path}
12+
#sed 's/^option java_package.*/option go_package = "${go_package}";/' protobuf/${path}
13+
}
14+
15+
tag=$1
16+
17+
# CloudState protocol
18+
fetch "protocol/cloudstate/entity.proto" $tag
19+
fetch "protocol/cloudstate/event_sourced.proto" $tag
20+
fetch "protocol/cloudstate/function.proto" $tag
21+
fetch "protocol/cloudstate/crdt.proto" $tag
22+
23+
# TCK shopping cart example
24+
fetch "example/shoppingcart/shoppingcart.proto" $tag
25+
fetch "example/shoppingcart/persistence/domain.proto" $tag
26+
27+
# CloudState frontend
28+
fetch "frontend/cloudstate/entity_key.proto" $tag
29+
30+
# dependencies
31+
fetch "proxy/grpc/reflection/v1alpha/reflection.proto" $tag
32+
fetch "frontend/google/api/annotations.proto" $tag
33+
fetch "frontend/google/api/http.proto" $tag

cloudstate/cloud_state.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from dataclasses import (dataclass, field)
2+
from typing import List
3+
import os
4+
5+
from concurrent import futures
6+
import grpc
7+
8+
from cloudstate.evensourced_servicer import CloudStateEventSourcedServicer
9+
from cloudstate.event_sourced_entity import EventSourcedEntity
10+
from cloudstate.discovery_servicer import CloudStateEntityDiscoveryServicer
11+
from cloudstate.entity_pb2_grpc import add_EntityDiscoveryServicer_to_server
12+
from pprint import pprint
13+
14+
from cloudstate.event_sourced_pb2_grpc import add_EventSourcedServicer_to_server
15+
16+
17+
@dataclass
18+
class CloudState:
19+
event_sourced_entities: List[EventSourcedEntity] = field(default_factory=list)
20+
21+
def register_event_sourced_entity(self, entity: EventSourcedEntity):
22+
self.event_sourced_entities.append(entity)
23+
return self
24+
25+
def start(self):
26+
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
27+
add_EntityDiscoveryServicer_to_server(CloudStateEntityDiscoveryServicer(self.event_sourced_entities), server)
28+
add_EventSourcedServicer_to_server(CloudStateEventSourcedServicer(self.event_sourced_entities),server)
29+
port = os.environ.get('HOST', '127.0.0.1') + ':' + os.environ.get('PORT', '8080')
30+
server.add_insecure_port(port)
31+
pprint('Starting Cloudstate on ' + port)
32+
server.start()
33+
server.wait_for_termination()

cloudstate/contexts.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from dataclasses import dataclass, field
2+
from typing import List
3+
4+
from cloudstate.entity_pb2 import ClientAction, Failure, Reply, Forward, SideEffect
5+
6+
7+
class Context:
8+
"""Root class of all contexts."""
9+
pass
10+
11+
12+
class ClientActionContext(Context):
13+
"""Context that provides client actions, which include failing and forwarding.
14+
These contexts are typically made available in response to commands."""
15+
16+
def __init__(self,command_id: int):
17+
self.command_id: int = command_id
18+
self.errors: List[str] = []
19+
self.effects:List[SideEffect] = []
20+
self.forward: Forward = None
21+
22+
def fail(self, error_message: str):
23+
"""Fail the command with the given message"""
24+
self.errors.append(error_message)
25+
26+
def has_errors(self):
27+
return len(self.errors) > 0
28+
29+
def create_client_action(self, result, allow_reply):
30+
client_action = ClientAction()
31+
if self.has_errors():
32+
failure = Failure()
33+
failure.command_id = self.command_id
34+
failure.description = str(self.errors)
35+
client_action.failure.CopyFrom(failure)
36+
elif result:
37+
if self.forward:
38+
raise Exception("Both a reply was returned, and a forward message was sent, choose one or the other.")
39+
else:
40+
reply = Reply()
41+
reply.payload.Pack(result)
42+
client_action.reply.CopyFrom(reply)
43+
elif self.forward:
44+
client_action.forward.CopyFrom(self.forward)
45+
elif allow_reply:
46+
return None
47+
else:
48+
raise Exception("No reply or forward returned by command handler!")
49+
return client_action

cloudstate/discovery_servicer.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2019 Lightbend Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import platform
16+
from dataclasses import dataclass
17+
from pprint import pprint
18+
from typing import List
19+
20+
from google.protobuf.descriptor_pb2 import FileDescriptorSet, FileDescriptorProto
21+
from google.protobuf.descriptor_pool import Default
22+
23+
from cloudstate import entity_pb2
24+
from cloudstate.entity_pb2_grpc import EntityDiscoveryServicer
25+
from cloudstate.event_sourced_entity import EventSourcedEntity
26+
27+
28+
@dataclass
29+
class CloudStateEntityDiscoveryServicer(EntityDiscoveryServicer):
30+
event_sourced_entities: List[EventSourcedEntity]
31+
32+
def discover(self, request, context):
33+
pprint(request)
34+
descriptor_set = FileDescriptorSet()
35+
for entity in self.event_sourced_entities:
36+
for descriptor in entity.file_descriptors:
37+
descriptor_set.file.append(FileDescriptorProto.FromString(descriptor.serialized_pb))
38+
descriptor_set.file.append(
39+
FileDescriptorProto.FromString(Default().FindFileByName('google/protobuf/empty.proto').serialized_pb)
40+
)
41+
descriptor_set.file.append(
42+
FileDescriptorProto.FromString(Default().FindFileByName('cloudstate/entity_key.proto').serialized_pb)
43+
)
44+
descriptor_set.file.append(
45+
FileDescriptorProto.FromString(Default().FindFileByName('google/protobuf/descriptor.proto').serialized_pb)
46+
)
47+
descriptor_set.file.append(
48+
FileDescriptorProto.FromString(Default().FindFileByName('google/api/annotations.proto').serialized_pb)
49+
)
50+
descriptor_set.file.append(
51+
FileDescriptorProto.FromString(Default().FindFileByName('google/api/http.proto').serialized_pb)
52+
)
53+
spec = entity_pb2.EntitySpec(
54+
service_info=entity_pb2.ServiceInfo(
55+
service_version='0.1.0',
56+
service_runtime='Python ' + platform.python_version() + ' [' + platform.python_implementation() + ' ' +
57+
platform.python_compiler() + ']',
58+
support_library_name='cloudstate-python-support',
59+
support_library_version='0.1.0'
60+
),
61+
entities=[
62+
entity_pb2.Entity(
63+
entity_type=entity.entity_type(),
64+
service_name=entity.service_descriptor.full_name,
65+
persistence_id=entity.persistence_id,
66+
)
67+
for entity in self.event_sourced_entities],
68+
proto=descriptor_set.SerializeToString()
69+
)
70+
return spec
71+
72+
def reportError(self, request, context):
73+
pprint(request)
74+
return

cloudstate/entity_key_pb2.py

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloudstate/entity_key_pb2_grpc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2+
import grpc
3+

0 commit comments

Comments
 (0)