Skip to content

Commit 2cef0a1

Browse files
author
Yi Tseng
authoredDec 18, 2020
Add Python setuptool support (p4lang#328)
* Add Python setuptool support Allows developers to install generated Python code via pip or setup.py * address comments * Fix README path in setup.py * typo * Use TravisCI to deploy PyPI package * Add pypi token
1 parent bd19174 commit 2cef0a1

18 files changed

+8473
-4
lines changed
 

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
docs/v1/build/
44
bazel-*
55
.DS_Store
6+
build
7+
dist
8+
*.egg-info

‎.travis.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ install:
1212
# protoc), then we generate the HTML for the spec.
1313
script:
1414
- docker run -t p4runtime-ci /p4runtime/codegen/compile_protos.sh /tmp || travis_terminate 1
15-
- ./CI/check_go.sh || travis_terminate 1 # TODO: remove previous step
15+
- ./CI/check_codegen.sh || travis_terminate 1 # TODO: remove previous step
1616
- docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-madoko:latest make || travis_terminate 1
1717
- ./tools/madokolint.py docs/v1/P4Runtime-Spec.mdk
1818

@@ -71,3 +71,13 @@ deploy:
7171
on:
7272
repo: p4lang/p4runtime
7373
branch: master
74+
- provider: pypi
75+
username: "__token__"
76+
password:
77+
secure: "ZV4yvWZDupmyyJHDF7/E0SgAR4WDnNu3gyCBMmslE4kpW0mKYC76hOUJJzcOirUrCUHPWNC0/CUC34hbClIaexXql3BBSAkm5MiSc9J1qDzSS6V9vVeMrGteDxXJZYFDmiWGtmsaWfATu486/FoiBIsvKygQK/hC9cPboVHkwLhXRHWEXnkBdKtd+8x/vWW8nG9p5iLp1s6ysYbUaTpuVrydnXyIOk+lNLTJFJSI7CZZSAxR5QiWMjZ43gD4pD5KZr7G16DlaM9fhRLH8D0wXiY7FcDoKPRC96jK73qZ9JHPBfUyNGz3h1TEdTlqUGuM8mq2TM66aomX+ybW8Q7LFwivoDetvhql7cF5l4H4pZ/oeManYqF0Q7qPRnPjhI0S74n+X9tL+9ARbuRArVjbdRDkOH9faz0aercekhfOwJhQ190dFrLAKi2gIW+VVWio19RHrs2qVsTRrWHbD9DDAMQQf7OmDqQOO7oni9jRNC+8DGLPxaebyMKNT5JAs7ssIBckzfoX+FMEnwUyviwWW9Cs6K5TE40GVoB/j2V9zlPGo2ldh5PYgTb97HWwpZtJkyqOZWlvw9C7+kPCWf/GI91yr9krWoye9XDx/BVuUdpwCK4aAW1PWt3qnWQKBOo37aCvhU9NDax5Rmy3tnl0cM0Q4StSwBW199lRX2orJd0="
78+
skip_existing: true
79+
before_deploy:
80+
- cd py
81+
on:
82+
repo: p4lang/p4runtime
83+
tags: true

‎CI/check_go.sh ‎CI/check_codegen.sh

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ THIS_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
77
pushd "$THIS_DIR/.." >/dev/null
88

99
rm -rf go/*
10-
./codegen/update_go.sh
10+
rm -rf py/p4
11+
./codegen/update.sh
1112

1213
diff="$(git status --porcelain go go.mod go.sum)"
1314

@@ -17,5 +18,13 @@ if [ ! -z "$diff" ]; then
1718
exit 1
1819
fi
1920

21+
diff="$(git status --porcelain py)"
22+
23+
if [ ! -z "$diff" ]; then
24+
echo "The generated Python files are not up-to-date"
25+
echo "You can regenerate them with './codegen/update_py.sh' and commit the changes"
26+
exit 1
27+
fi
28+
2029
popd >/dev/null
2130

‎README.md

+28-2
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,36 @@ processes.
145145
approve.
146146

147147
When updating the Protobuf files in a pull request, you will also need to update
148-
the generated Go files, which are hosted in this repository under
149-
[go/](go/). This can be done easily by running `./codegen/update_go.sh`,
148+
the generated Go and Python files, which are hosted in this repository under
149+
[go/](go/) and [py/](py/). This can be done easily by running `./codegen/update.sh`,
150150
provided docker is installed and your user is part of the "docker" group
151151
(which means that the `docker` command can be executed without `sudo`).
152152

153+
## Use generated P4Runtime library
154+
155+
### Go
156+
157+
To include the P4Runtime Go library to your project, you can add this repository url
158+
to your `go.mod` file, for example:
159+
160+
```
161+
module your_module_name
162+
163+
go 1.13
164+
165+
require (
166+
github.com/p4lang/p4runtime v1.3.0
167+
)
168+
```
169+
170+
### Python
171+
172+
To install P4Runtime Python library, use the `pip3` command:
173+
174+
```bash
175+
pip3 install p4runtime
176+
# Or specify the version
177+
pip3 install p4runtime==1.3.0
178+
```
153179

154180
[P4 Slack Workspace]: https://p4-lang.slack.com/join/shared_invite/enQtODA0NzY4Mjc5MTExLTRlMWVmN2I5ZTY4MTAzMDI3MGQ1OTZjM2ZmM2Q1MWE2YzZjYTQ2ZWMyMGUyYjQ2ZmIxMjFjZDE4ZThiN2ZkZWI

‎codegen/update_go.sh ‎codegen/update.sh

+5
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ docker run --rm \
1414
-v "$tmpdir:/tmp/gen" \
1515
p4runtime-ci /p4runtime/codegen/compile_protos.sh /tmp/gen
1616

17+
# Go
1718
cp -r "$tmpdir"/go_out/github.com/p4lang/p4runtime/go/* go/
1819

20+
# Python
21+
cp -r "$tmpdir"/py_out/p4 py/
22+
find py/p4 -type d -exec touch {}/__init__.py \;
23+
1924
# Cleanup files owned by root user
2025
docker run --rm \
2126
-v "$tmpdir:/tmp/gen" \

‎py/p4/__init__.py

Whitespace-only changes.

‎py/p4/config/__init__.py

Whitespace-only changes.

‎py/p4/config/v1/__init__.py

Whitespace-only changes.

‎py/p4/config/v1/p4info_pb2.py

+1,890
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎py/p4/config/v1/p4info_pb2_grpc.py

+3
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+

‎py/p4/config/v1/p4types_pb2.py

+2,145
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎py/p4/config/v1/p4types_pb2_grpc.py

+3
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+

‎py/p4/v1/__init__.py

Whitespace-only changes.

‎py/p4/v1/p4data_pb2.py

+452
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎py/p4/v1/p4data_pb2_grpc.py

+3
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+

‎py/p4/v1/p4runtime_pb2.py

+3,753
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎py/p4/v1/p4runtime_pb2_grpc.py

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2+
import grpc
3+
4+
from p4.v1 import p4runtime_pb2 as p4_dot_v1_dot_p4runtime__pb2
5+
6+
7+
class P4RuntimeStub(object):
8+
# missing associated documentation comment in .proto file
9+
pass
10+
11+
def __init__(self, channel):
12+
"""Constructor.
13+
14+
Args:
15+
channel: A grpc.Channel.
16+
"""
17+
self.Write = channel.unary_unary(
18+
'/p4.v1.P4Runtime/Write',
19+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.WriteRequest.SerializeToString,
20+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.WriteResponse.FromString,
21+
)
22+
self.Read = channel.unary_stream(
23+
'/p4.v1.P4Runtime/Read',
24+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.ReadRequest.SerializeToString,
25+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.ReadResponse.FromString,
26+
)
27+
self.SetForwardingPipelineConfig = channel.unary_unary(
28+
'/p4.v1.P4Runtime/SetForwardingPipelineConfig',
29+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigRequest.SerializeToString,
30+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigResponse.FromString,
31+
)
32+
self.GetForwardingPipelineConfig = channel.unary_unary(
33+
'/p4.v1.P4Runtime/GetForwardingPipelineConfig',
34+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigRequest.SerializeToString,
35+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigResponse.FromString,
36+
)
37+
self.StreamChannel = channel.stream_stream(
38+
'/p4.v1.P4Runtime/StreamChannel',
39+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageRequest.SerializeToString,
40+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageResponse.FromString,
41+
)
42+
self.Capabilities = channel.unary_unary(
43+
'/p4.v1.P4Runtime/Capabilities',
44+
request_serializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesRequest.SerializeToString,
45+
response_deserializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesResponse.FromString,
46+
)
47+
48+
49+
class P4RuntimeServicer(object):
50+
# missing associated documentation comment in .proto file
51+
pass
52+
53+
def Write(self, request, context):
54+
"""Update one or more P4 entities on the target.
55+
"""
56+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
57+
context.set_details('Method not implemented!')
58+
raise NotImplementedError('Method not implemented!')
59+
60+
def Read(self, request, context):
61+
"""Read one or more P4 entities from the target.
62+
"""
63+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
64+
context.set_details('Method not implemented!')
65+
raise NotImplementedError('Method not implemented!')
66+
67+
def SetForwardingPipelineConfig(self, request, context):
68+
"""Sets the P4 forwarding-pipeline config.
69+
"""
70+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
71+
context.set_details('Method not implemented!')
72+
raise NotImplementedError('Method not implemented!')
73+
74+
def GetForwardingPipelineConfig(self, request, context):
75+
"""Gets the current P4 forwarding-pipeline config.
76+
"""
77+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
78+
context.set_details('Method not implemented!')
79+
raise NotImplementedError('Method not implemented!')
80+
81+
def StreamChannel(self, request_iterator, context):
82+
"""Represents the bidirectional stream between the controller and the
83+
switch (initiated by the controller), and is managed for the following
84+
purposes:
85+
- connection initiation through client arbitration
86+
- indicating switch session liveness: the session is live when switch
87+
sends a positive client arbitration update to the controller, and is
88+
considered dead when either the stream breaks or the switch sends a
89+
negative update for client arbitration
90+
- the controller sending/receiving packets to/from the switch
91+
- streaming of notifications from the switch
92+
"""
93+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
94+
context.set_details('Method not implemented!')
95+
raise NotImplementedError('Method not implemented!')
96+
97+
def Capabilities(self, request, context):
98+
# missing associated documentation comment in .proto file
99+
pass
100+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
101+
context.set_details('Method not implemented!')
102+
raise NotImplementedError('Method not implemented!')
103+
104+
105+
def add_P4RuntimeServicer_to_server(servicer, server):
106+
rpc_method_handlers = {
107+
'Write': grpc.unary_unary_rpc_method_handler(
108+
servicer.Write,
109+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.WriteRequest.FromString,
110+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.WriteResponse.SerializeToString,
111+
),
112+
'Read': grpc.unary_stream_rpc_method_handler(
113+
servicer.Read,
114+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.ReadRequest.FromString,
115+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.ReadResponse.SerializeToString,
116+
),
117+
'SetForwardingPipelineConfig': grpc.unary_unary_rpc_method_handler(
118+
servicer.SetForwardingPipelineConfig,
119+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigRequest.FromString,
120+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigResponse.SerializeToString,
121+
),
122+
'GetForwardingPipelineConfig': grpc.unary_unary_rpc_method_handler(
123+
servicer.GetForwardingPipelineConfig,
124+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigRequest.FromString,
125+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigResponse.SerializeToString,
126+
),
127+
'StreamChannel': grpc.stream_stream_rpc_method_handler(
128+
servicer.StreamChannel,
129+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageRequest.FromString,
130+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageResponse.SerializeToString,
131+
),
132+
'Capabilities': grpc.unary_unary_rpc_method_handler(
133+
servicer.Capabilities,
134+
request_deserializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesRequest.FromString,
135+
response_serializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesResponse.SerializeToString,
136+
),
137+
}
138+
generic_handler = grpc.method_handlers_generic_handler(
139+
'p4.v1.P4Runtime', rpc_method_handlers)
140+
server.add_generic_rpc_handlers((generic_handler,))

‎py/setup.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
from setuptools import setup, find_packages
3+
this_dir = os.path.dirname(os.path.realpath(__file__))
4+
project_root = os.path.abspath(os.path.join(this_dir, os.pardir))
5+
6+
setup(
7+
name = "p4runtime",
8+
version = "1.3.0",
9+
packages = find_packages("."),
10+
install_requires = [
11+
"protobuf >= 3.6.1",
12+
"grpcio >= 1.17.2",
13+
"googleapis-common-protos >= 1.52"
14+
],
15+
author = "P4 API Working Group",
16+
author_email = "p4-api@lists.p4.org",
17+
classifiers = [
18+
'License :: OSI Approved :: Apache Software License',
19+
'Programming Language :: Python',
20+
'Programming Language :: Python :: 3',
21+
],
22+
description = "The P4 Runtime protocol",
23+
long_description = open(project_root + "/README.md").read(),
24+
long_description_content_type = "text/markdown",
25+
license = "Apache-2.0",
26+
url = "https://github.com/p4lang/p4runtime"
27+
)

0 commit comments

Comments
 (0)
Please sign in to comment.