Include core in Python distribution

pull/4457/head
Masood Malekghassemi 9 years ago
parent bbaad2a7e4
commit 116982ea89
  1. 9
      .gitignore
  2. 8
      MANIFEST.in
  3. 4
      build.yaml
  4. 0
      requirements.txt
  5. 0
      setup.cfg
  6. 42
      setup.py
  7. 4
      src/python/grpcio/MANIFEST.in
  8. 8
      src/python/grpcio/commands.py
  9. 4
      src/python/grpcio/grpc/_cython/_cygrpc/call.pxd.pxi
  10. 30
      src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
  11. 4
      src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi
  12. 44
      src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
  13. 6
      src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pxd.pxi
  14. 56
      src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
  15. 21
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
  16. 59
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  17. 0
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  18. 34
      src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
  19. 238
      src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
  20. 7
      src/python/grpcio/grpc/_cython/_cygrpc/server.pxd.pxi
  21. 56
      src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
  22. 8
      src/python/grpcio/grpc/_cython/cygrpc.pxd
  23. 84
      src/python/grpcio/grpc/_cython/cygrpc.pyx
  24. 195
      src/python/grpcio/grpc_core_dependencies.py
  25. 2
      src/python/grpcio/tests/unit/_cython/test_utilities.py
  26. 19
      src/python/grpcio/tox.ini
  27. 13
      templates/src/python/grpcio/grpc_core_dependencies.py.template
  28. 6
      tools/buildgen/plugins/transitive_dependencies.py
  29. 2
      tools/distrib/python/submit.py
  30. 1
      tools/jenkins/grpc_interop_python/Dockerfile
  31. 2
      tools/jenkins/grpc_interop_python/build_interop.sh
  32. 6
      tools/run_tests/build_python.sh
  33. 8
      tools/run_tests/run_interop_tests.py
  34. 6
      tools/run_tests/run_python.sh
  35. 17
      tox.ini

9
.gitignore vendored

@ -4,8 +4,13 @@ gens
libs libs
objs objs
# Python virtual environments # Python items
python*_virtual_environment .coverage*
.eggs
.tox
htmlcov/
dist/
*.egg
# gcov coverage data # gcov coverage data
reports reports

@ -0,0 +1,8 @@
graft src/python/grpcio/grpc
graft src/python/grpcio/tests
graft src/core
graft include/grpc
include src/python/grpcio/commands.py
include src/python/grpcio/grpc_core_dependencies.py
include src/python/grpcio/README.rst
include requirements.txt

@ -2474,3 +2474,7 @@ node_modules:
- src/node/ext/server.cc - src/node/ext/server.cc
- src/node/ext/server_credentials.cc - src/node/ext/server_credentials.cc
- src/node/ext/timeval.cc - src/node/ext/timeval.cc
python_dependencies:
deps:
- grpc
- gpr

@ -37,11 +37,16 @@ from distutils import core as _core
from distutils import extension as _extension from distutils import extension as _extension
import setuptools import setuptools
PYTHON_STEM = './src/python/grpcio/'
CORE_INCLUDE = ('./include', './',)
# Ensure we're in the proper directory whether or not we're being used by pip. # Ensure we're in the proper directory whether or not we're being used by pip.
os.chdir(os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, PYTHON_STEM)
# Break import-style to ensure we can actually find our commands module. # Break import-style to ensure we can actually find our in-repo dependencies.
import commands import commands
import grpc_core_dependencies
# Environment variable to determine whether or not the Cython extension should # Environment variable to determine whether or not the Cython extension should
# *use* Cython or use the generated C files. Note that this requires the C files # *use* Cython or use the generated C files. Note that this requires the C files
@ -59,23 +64,13 @@ INSTALL_TESTS = os.environ.get('GRPC_PYTHON_INSTALL_TESTS', False)
CYTHON_EXTENSION_PACKAGE_NAMES = () CYTHON_EXTENSION_PACKAGE_NAMES = ()
CYTHON_EXTENSION_MODULE_NAMES = ( CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)
'grpc._cython.cygrpc',
'grpc._cython._cygrpc.call',
'grpc._cython._cygrpc.channel',
'grpc._cython._cygrpc.completion_queue',
'grpc._cython._cygrpc.credentials',
'grpc._cython._cygrpc.records',
'grpc._cython._cygrpc.server',
)
EXTENSION_INCLUDE_DIRECTORIES = ( EXTENSION_INCLUDE_DIRECTORIES = (PYTHON_STEM,) + CORE_INCLUDE
'.',
)
EXTENSION_LIBRARIES = ( EXTENSION_LIBRARIES = (
'grpc', 'ssl',
'gpr', 'crypto',
) )
if not "darwin" in sys.platform: if not "darwin" in sys.platform:
EXTENSION_LIBRARIES += ('rt',) EXTENSION_LIBRARIES += ('rt',)
@ -84,11 +79,13 @@ if not "darwin" in sys.platform:
def cython_extensions(package_names, module_names, include_dirs, libraries, def cython_extensions(package_names, module_names, include_dirs, libraries,
build_with_cython=False): build_with_cython=False):
file_extension = 'pyx' if build_with_cython else 'c' file_extension = 'pyx' if build_with_cython else 'c'
module_files = [name.replace('.', '/') + '.' + file_extension module_files = [os.path.join(PYTHON_STEM,
name.replace('.', '/') + '.' + file_extension)
for name in module_names] for name in module_names]
extensions = [ extensions = [
_extension.Extension( _extension.Extension(
name=module_name, sources=[module_file], name=module_name,
sources=[module_file] + grpc_core_dependencies.CORE_SOURCE_FILES,
include_dirs=include_dirs, libraries=libraries, include_dirs=include_dirs, libraries=libraries,
define_macros=[('CYTHON_TRACE_NOGIL', 1)] if ENABLE_CYTHON_TRACING else [] define_macros=[('CYTHON_TRACE_NOGIL', 1)] if ENABLE_CYTHON_TRACING else []
) for (module_name, module_file) in zip(module_names, module_files) ) for (module_name, module_file) in zip(module_names, module_files)
@ -97,6 +94,7 @@ def cython_extensions(package_names, module_names, include_dirs, libraries,
import Cython.Build import Cython.Build
return Cython.Build.cythonize( return Cython.Build.cythonize(
extensions, extensions,
include_path=include_dirs,
compiler_directives={'linetrace': bool(ENABLE_CYTHON_TRACING)}) compiler_directives={'linetrace': bool(ENABLE_CYTHON_TRACING)})
else: else:
return extensions return extensions
@ -107,7 +105,7 @@ CYTHON_EXTENSION_MODULES = cython_extensions(
bool(BUILD_WITH_CYTHON)) bool(BUILD_WITH_CYTHON))
PACKAGE_DIRECTORIES = { PACKAGE_DIRECTORIES = {
'': '.', '': PYTHON_STEM,
} }
INSTALL_REQUIRES = ( INSTALL_REQUIRES = (
@ -157,16 +155,18 @@ TEST_RUNNER = 'tests:Runner'
PACKAGE_DATA = {} PACKAGE_DATA = {}
if INSTALL_TESTS: if INSTALL_TESTS:
PACKAGE_DATA = dict(PACKAGE_DATA, **TEST_PACKAGE_DATA) PACKAGE_DATA = dict(PACKAGE_DATA, **TEST_PACKAGE_DATA)
PACKAGES = setuptools.find_packages('.') PACKAGES = setuptools.find_packages(PYTHON_STEM)
else: else:
PACKAGES = setuptools.find_packages('.', exclude=['tests', 'tests.*']) PACKAGES = setuptools.find_packages(
PYTHON_STEM, exclude=['tests', 'tests.*'])
setuptools.setup( setuptools.setup(
name='grpcio', name='grpcio',
version='0.12.0b0', version='0.12.0b1',
ext_modules=CYTHON_EXTENSION_MODULES, ext_modules=CYTHON_EXTENSION_MODULES,
packages=list(PACKAGES), packages=list(PACKAGES),
package_dir=PACKAGE_DIRECTORIES, package_dir=PACKAGE_DIRECTORIES,
package_data=PACKAGE_DATA,
install_requires=INSTALL_REQUIRES, install_requires=INSTALL_REQUIRES,
setup_requires=SETUP_REQUIRES, setup_requires=SETUP_REQUIRES,
cmdclass=COMMAND_CLASS, cmdclass=COMMAND_CLASS,

@ -1,4 +0,0 @@
graft grpc
graft tests
include commands.py
include requirements.txt

@ -40,6 +40,8 @@ import setuptools
from setuptools.command import build_py from setuptools.command import build_py
from setuptools.command import test from setuptools.command import test
PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
CONF_PY_ADDENDUM = """ CONF_PY_ADDENDUM = """
extensions.append('sphinx.ext.napoleon') extensions.append('sphinx.ext.napoleon')
napoleon_google_docstring = True napoleon_google_docstring = True
@ -68,7 +70,7 @@ class SphinxDocumentation(setuptools.Command):
import sphinx.apidoc import sphinx.apidoc
metadata = self.distribution.metadata metadata = self.distribution.metadata
src_dir = os.path.join( src_dir = os.path.join(
os.getcwd(), self.distribution.package_dir[''], 'grpc') PYTHON_STEM, self.distribution.package_dir[''], 'grpc')
sys.path.append(src_dir) sys.path.append(src_dir)
sphinx.apidoc.main([ sphinx.apidoc.main([
'', '--force', '--full', '-H', metadata.name, '-A', metadata.author, '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
@ -104,7 +106,7 @@ class BuildProtoModules(setuptools.Command):
include_regex = re.compile(self.include) include_regex = re.compile(self.include)
exclude_regex = re.compile(self.exclude) if self.exclude else None exclude_regex = re.compile(self.exclude) if self.exclude else None
paths = [] paths = []
root_directory = os.getcwd() root_directory = PYTHON_STEM
for walk_root, directories, filenames in os.walk(root_directory): for walk_root, directories, filenames in os.walk(root_directory):
for filename in filenames: for filename in filenames:
path = os.path.join(walk_root, filename) path = os.path.join(walk_root, filename)
@ -140,7 +142,7 @@ class BuildProjectMetadata(setuptools.Command):
pass pass
def run(self): def run(self):
with open('grpc/_grpcio_metadata.py', 'w') as module_file: with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'), 'w') as module_file:
module_file.write('__version__ = """{}"""'.format( module_file.write('__version__ = """{}"""'.format(
self.distribution.get_version())) self.distribution.get_version()))

@ -27,11 +27,9 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
cdef class Call: cdef class Call:
cdef grpc.grpc_call *c_call cdef grpc_call *c_call
cdef list references cdef list references

@ -29,10 +29,6 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport credentials
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
cdef class Call: cdef class Call:
@ -44,24 +40,24 @@ cdef class Call:
def start_batch(self, operations, tag): def start_batch(self, operations, tag):
if not self.is_valid: if not self.is_valid:
raise ValueError("invalid call object cannot be used from Python") raise ValueError("invalid call object cannot be used from Python")
cdef records.Operations cy_operations = records.Operations(operations) cdef Operations cy_operations = Operations(operations)
cdef records.OperationTag operation_tag = records.OperationTag(tag) cdef OperationTag operation_tag = OperationTag(tag)
operation_tag.operation_call = self operation_tag.operation_call = self
operation_tag.batch_operations = cy_operations operation_tag.batch_operations = cy_operations
cpython.Py_INCREF(operation_tag) cpython.Py_INCREF(operation_tag)
return grpc.grpc_call_start_batch( return grpc_call_start_batch(
self.c_call, cy_operations.c_ops, cy_operations.c_nops, self.c_call, cy_operations.c_ops, cy_operations.c_nops,
<cpython.PyObject *>operation_tag, NULL) <cpython.PyObject *>operation_tag, NULL)
def cancel( def cancel(
self, grpc.grpc_status_code error_code=grpc.GRPC_STATUS__DO_NOT_USE, self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE,
details=None): details=None):
if not self.is_valid: if not self.is_valid:
raise ValueError("invalid call object cannot be used from Python") raise ValueError("invalid call object cannot be used from Python")
if (details is None) != (error_code == grpc.GRPC_STATUS__DO_NOT_USE): if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE):
raise ValueError("if error_code is specified, so must details " raise ValueError("if error_code is specified, so must details "
"(and vice-versa)") "(and vice-versa)")
if error_code != grpc.GRPC_STATUS__DO_NOT_USE: if error_code != GRPC_STATUS__DO_NOT_USE:
if isinstance(details, bytes): if isinstance(details, bytes):
pass pass
elif isinstance(details, basestring): elif isinstance(details, basestring):
@ -69,25 +65,25 @@ cdef class Call:
else: else:
raise TypeError("expected details to be str or bytes") raise TypeError("expected details to be str or bytes")
self.references.append(details) self.references.append(details)
return grpc.grpc_call_cancel_with_status( return grpc_call_cancel_with_status(
self.c_call, error_code, details, NULL) self.c_call, error_code, details, NULL)
else: else:
return grpc.grpc_call_cancel(self.c_call, NULL) return grpc_call_cancel(self.c_call, NULL)
def set_credentials( def set_credentials(
self, credentials.CallCredentials call_credentials not None): self, CallCredentials call_credentials not None):
return grpc.grpc_call_set_credentials( return grpc_call_set_credentials(
self.c_call, call_credentials.c_credentials) self.c_call, call_credentials.c_credentials)
def peer(self): def peer(self):
cdef char *peer = grpc.grpc_call_get_peer(self.c_call) cdef char *peer = grpc_call_get_peer(self.c_call)
result = <bytes>peer result = <bytes>peer
grpc.gpr_free(peer) gpr_free(peer)
return result return result
def __dealloc__(self): def __dealloc__(self):
if self.c_call != NULL: if self.c_call != NULL:
grpc.grpc_call_destroy(self.c_call) grpc_call_destroy(self.c_call)
# The object *should* always be valid from Python. Used for debugging. # The object *should* always be valid from Python. Used for debugging.
@property @property

@ -27,10 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
cdef class Channel: cdef class Channel:
cdef grpc.grpc_channel *c_channel cdef grpc_channel *c_channel
cdef list references cdef list references

@ -29,18 +29,12 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport completion_queue
from grpc._cython._cygrpc cimport credentials
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
cdef class Channel: cdef class Channel:
def __cinit__(self, target, records.ChannelArgs arguments=None, def __cinit__(self, target, ChannelArgs arguments=None,
credentials.ChannelCredentials channel_credentials=None): ChannelCredentials channel_credentials=None):
cdef grpc.grpc_channel_args *c_arguments = NULL cdef grpc_channel_args *c_arguments = NULL
self.c_channel = NULL self.c_channel = NULL
self.references = [] self.references = []
if arguments is not None: if arguments is not None:
@ -52,18 +46,18 @@ cdef class Channel:
else: else:
raise TypeError("expected target to be str or bytes") raise TypeError("expected target to be str or bytes")
if channel_credentials is None: if channel_credentials is None:
self.c_channel = grpc.grpc_insecure_channel_create(target, c_arguments, self.c_channel = grpc_insecure_channel_create(target, c_arguments,
NULL) NULL)
else: else:
self.c_channel = grpc.grpc_secure_channel_create( self.c_channel = grpc_secure_channel_create(
channel_credentials.c_credentials, target, c_arguments, NULL) channel_credentials.c_credentials, target, c_arguments, NULL)
self.references.append(channel_credentials) self.references.append(channel_credentials)
self.references.append(target) self.references.append(target)
self.references.append(arguments) self.references.append(arguments)
def create_call(self, call.Call parent, int flags, def create_call(self, Call parent, int flags,
completion_queue.CompletionQueue queue not None, CompletionQueue queue not None,
method, host, records.Timespec deadline not None): method, host, Timespec deadline not None):
if queue.is_shutting_down: if queue.is_shutting_down:
raise ValueError("queue must not be shutting down or shutdown") raise ValueError("queue must not be shutting down or shutdown")
if isinstance(method, bytes): if isinstance(method, bytes):
@ -82,36 +76,36 @@ cdef class Channel:
host_c_string = host host_c_string = host
else: else:
raise TypeError("expected host to be str, bytes, or None") raise TypeError("expected host to be str, bytes, or None")
cdef call.Call operation_call = call.Call() cdef Call operation_call = Call()
operation_call.references = [self, method, host, queue] operation_call.references = [self, method, host, queue]
cdef grpc.grpc_call *parent_call = NULL cdef grpc_call *parent_call = NULL
if parent is not None: if parent is not None:
parent_call = parent.c_call parent_call = parent.c_call
operation_call.c_call = grpc.grpc_channel_create_call( operation_call.c_call = grpc_channel_create_call(
self.c_channel, parent_call, flags, self.c_channel, parent_call, flags,
queue.c_completion_queue, method, host_c_string, deadline.c_time, queue.c_completion_queue, method, host_c_string, deadline.c_time,
NULL) NULL)
return operation_call return operation_call
def check_connectivity_state(self, bint try_to_connect): def check_connectivity_state(self, bint try_to_connect):
return grpc.grpc_channel_check_connectivity_state(self.c_channel, return grpc_channel_check_connectivity_state(self.c_channel,
try_to_connect) try_to_connect)
def watch_connectivity_state( def watch_connectivity_state(
self, last_observed_state, records.Timespec deadline not None, self, last_observed_state, Timespec deadline not None,
completion_queue.CompletionQueue queue not None, tag): CompletionQueue queue not None, tag):
cdef records.OperationTag operation_tag = records.OperationTag(tag) cdef OperationTag operation_tag = OperationTag(tag)
cpython.Py_INCREF(operation_tag) cpython.Py_INCREF(operation_tag)
grpc.grpc_channel_watch_connectivity_state( grpc_channel_watch_connectivity_state(
self.c_channel, last_observed_state, deadline.c_time, self.c_channel, last_observed_state, deadline.c_time,
queue.c_completion_queue, <cpython.PyObject *>operation_tag) queue.c_completion_queue, <cpython.PyObject *>operation_tag)
def target(self): def target(self):
cdef char * target = grpc.grpc_channel_get_target(self.c_channel) cdef char * target = grpc_channel_get_target(self.c_channel)
result = <bytes>target result = <bytes>target
grpc.gpr_free(target) gpr_free(target)
return result return result
def __dealloc__(self): def __dealloc__(self):
if self.c_channel != NULL: if self.c_channel != NULL:
grpc.grpc_channel_destroy(self.c_channel) grpc_channel_destroy(self.c_channel)

@ -27,15 +27,13 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
cdef class CompletionQueue: cdef class CompletionQueue:
cdef grpc.grpc_completion_queue *c_completion_queue cdef grpc_completion_queue *c_completion_queue
cdef object poll_condition cdef object poll_condition
cdef bint is_polling cdef bint is_polling
cdef bint is_shutting_down cdef bint is_shutting_down
cdef bint is_shutdown cdef bint is_shutdown
cdef _interpret_event(self, grpc.grpc_event event) cdef _interpret_event(self, grpc_event event)

@ -29,10 +29,6 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
import threading import threading
import time import time
@ -40,29 +36,29 @@ import time
cdef class CompletionQueue: cdef class CompletionQueue:
def __cinit__(self): def __cinit__(self):
self.c_completion_queue = grpc.grpc_completion_queue_create(NULL) self.c_completion_queue = grpc_completion_queue_create(NULL)
self.is_shutting_down = False self.is_shutting_down = False
self.is_shutdown = False self.is_shutdown = False
self.poll_condition = threading.Condition() self.poll_condition = threading.Condition()
self.is_polling = False self.is_polling = False
cdef _interpret_event(self, grpc.grpc_event event): cdef _interpret_event(self, grpc_event event):
cdef records.OperationTag tag = None cdef OperationTag tag = None
cdef object user_tag = None cdef object user_tag = None
cdef call.Call operation_call = None cdef Call operation_call = None
cdef records.CallDetails request_call_details = None cdef CallDetails request_call_details = None
cdef records.Metadata request_metadata = None cdef Metadata request_metadata = None
cdef records.Operations batch_operations = None cdef Operations batch_operations = None
if event.type == grpc.GRPC_QUEUE_TIMEOUT: if event.type == GRPC_QUEUE_TIMEOUT:
return records.Event( return Event(
event.type, False, None, None, None, None, False, None) event.type, False, None, None, None, None, False, None)
elif event.type == grpc.GRPC_QUEUE_SHUTDOWN: elif event.type == GRPC_QUEUE_SHUTDOWN:
self.is_shutdown = True self.is_shutdown = True
return records.Event( return Event(
event.type, True, None, None, None, None, False, None) event.type, True, None, None, None, None, False, None)
else: else:
if event.tag != NULL: if event.tag != NULL:
tag = <records.OperationTag>event.tag tag = <OperationTag>event.tag
# We receive event tags only after they've been inc-ref'd elsewhere in # We receive event tags only after they've been inc-ref'd elsewhere in
# the code. # the code.
cpython.Py_DECREF(tag) cpython.Py_DECREF(tag)
@ -77,19 +73,19 @@ cdef class CompletionQueue:
# Stuff in the tag not explicitly handled by us needs to live through # Stuff in the tag not explicitly handled by us needs to live through
# the life of the call # the life of the call
operation_call.references.extend(tag.references) operation_call.references.extend(tag.references)
return records.Event( return Event(
event.type, event.success, user_tag, operation_call, event.type, event.success, user_tag, operation_call,
request_call_details, request_metadata, tag.is_new_request, request_call_details, request_metadata, tag.is_new_request,
batch_operations) batch_operations)
def poll(self, records.Timespec deadline=None): def poll(self, Timespec deadline=None):
# We name this 'poll' to avoid problems with CPython's expectations for # We name this 'poll' to avoid problems with CPython's expectations for
# 'special' methods (like next and __next__). # 'special' methods (like next and __next__).
cdef grpc.gpr_timespec c_deadline = grpc.gpr_inf_future( cdef gpr_timespec c_deadline = gpr_inf_future(
grpc.GPR_CLOCK_REALTIME) GPR_CLOCK_REALTIME)
if deadline is not None: if deadline is not None:
c_deadline = deadline.c_time c_deadline = deadline.c_time
cdef grpc.grpc_event event cdef grpc_event event
# Poll within a critical section # Poll within a critical section
# TODO(atash) consider making queue polling contention a hard error to # TODO(atash) consider making queue polling contention a hard error to
@ -99,21 +95,21 @@ cdef class CompletionQueue:
self.poll_condition.wait(float(deadline) - time.time()) self.poll_condition.wait(float(deadline) - time.time())
self.is_polling = True self.is_polling = True
with nogil: with nogil:
event = grpc.grpc_completion_queue_next( event = grpc_completion_queue_next(
self.c_completion_queue, c_deadline, NULL) self.c_completion_queue, c_deadline, NULL)
with self.poll_condition: with self.poll_condition:
self.is_polling = False self.is_polling = False
self.poll_condition.notify() self.poll_condition.notify()
return self._interpret_event(event) return self._interpret_event(event)
def pluck(self, records.OperationTag tag, records.Timespec deadline=None): def pluck(self, OperationTag tag, Timespec deadline=None):
# Plucking a 'None' tag is equivalent to passing control to GRPC core until # Plucking a 'None' tag is equivalent to passing control to GRPC core until
# the deadline. # the deadline.
cdef grpc.gpr_timespec c_deadline = grpc.gpr_inf_future( cdef gpr_timespec c_deadline = gpr_inf_future(
grpc.GPR_CLOCK_REALTIME) GPR_CLOCK_REALTIME)
if deadline is not None: if deadline is not None:
c_deadline = deadline.c_time c_deadline = deadline.c_time
cdef grpc.grpc_event event cdef grpc_event event
# Poll within a critical section # Poll within a critical section
# TODO(atash) consider making queue polling contention a hard error to # TODO(atash) consider making queue polling contention a hard error to
@ -123,7 +119,7 @@ cdef class CompletionQueue:
self.poll_condition.wait(float(deadline) - time.time()) self.poll_condition.wait(float(deadline) - time.time())
self.is_polling = True self.is_polling = True
with nogil: with nogil:
event = grpc.grpc_completion_queue_pluck( event = grpc_completion_queue_pluck(
self.c_completion_queue, <cpython.PyObject *>tag, c_deadline, NULL) self.c_completion_queue, <cpython.PyObject *>tag, c_deadline, NULL)
with self.poll_condition: with self.poll_condition:
self.is_polling = False self.is_polling = False
@ -131,13 +127,13 @@ cdef class CompletionQueue:
return self._interpret_event(event) return self._interpret_event(event)
def shutdown(self): def shutdown(self):
grpc.grpc_completion_queue_shutdown(self.c_completion_queue) grpc_completion_queue_shutdown(self.c_completion_queue)
self.is_shutting_down = True self.is_shutting_down = True
def clear(self): def clear(self):
if not self.is_shutting_down: if not self.is_shutting_down:
raise ValueError('queue must be shutting down to be cleared') raise ValueError('queue must be shutting down to be cleared')
while self.poll().type != grpc.GRPC_QUEUE_SHUTDOWN: while self.poll().type != GRPC_QUEUE_SHUTDOWN:
pass pass
def __dealloc__(self): def __dealloc__(self):
@ -147,4 +143,4 @@ cdef class CompletionQueue:
self.shutdown() self.shutdown()
while not self.is_shutdown: while not self.is_shutdown:
self.poll() self.poll()
grpc.grpc_completion_queue_destroy(self.c_completion_queue) grpc_completion_queue_destroy(self.c_completion_queue)

@ -29,27 +29,24 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
cdef class ChannelCredentials: cdef class ChannelCredentials:
cdef grpc.grpc_channel_credentials *c_credentials cdef grpc_channel_credentials *c_credentials
cdef grpc.grpc_ssl_pem_key_cert_pair c_ssl_pem_key_cert_pair cdef grpc_ssl_pem_key_cert_pair c_ssl_pem_key_cert_pair
cdef list references cdef list references
cdef class CallCredentials: cdef class CallCredentials:
cdef grpc.grpc_call_credentials *c_credentials cdef grpc_call_credentials *c_credentials
cdef list references cdef list references
cdef class ServerCredentials: cdef class ServerCredentials:
cdef grpc.grpc_server_credentials *c_credentials cdef grpc_server_credentials *c_credentials
cdef grpc.grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs
cdef size_t c_ssl_pem_key_cert_pairs_count cdef size_t c_ssl_pem_key_cert_pairs_count
cdef list references cdef list references
@ -59,16 +56,16 @@ cdef class CredentialsMetadataPlugin:
cdef object plugin_callback cdef object plugin_callback
cdef str plugin_name cdef str plugin_name
cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self) cdef grpc_metadata_credentials_plugin make_c_plugin(self)
cdef class AuthMetadataContext: cdef class AuthMetadataContext:
cdef grpc.grpc_auth_metadata_context context cdef grpc_auth_metadata_context context
cdef void plugin_get_metadata( cdef void plugin_get_metadata(
void *state, grpc.grpc_auth_metadata_context context, void *state, grpc_auth_metadata_context context,
grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil
cdef void plugin_destroy_c_plugin_state(void *state) cdef void plugin_destroy_c_plugin_state(void *state)

@ -29,9 +29,6 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
cdef class ChannelCredentials: cdef class ChannelCredentials:
@ -49,7 +46,7 @@ cdef class ChannelCredentials:
def __dealloc__(self): def __dealloc__(self):
if self.c_credentials != NULL: if self.c_credentials != NULL:
grpc.grpc_channel_credentials_release(self.c_credentials) grpc_channel_credentials_release(self.c_credentials)
cdef class CallCredentials: cdef class CallCredentials:
@ -66,7 +63,7 @@ cdef class CallCredentials:
def __dealloc__(self): def __dealloc__(self):
if self.c_credentials != NULL: if self.c_credentials != NULL:
grpc.grpc_call_credentials_release(self.c_credentials) grpc_call_credentials_release(self.c_credentials)
cdef class ServerCredentials: cdef class ServerCredentials:
@ -77,7 +74,7 @@ cdef class ServerCredentials:
def __dealloc__(self): def __dealloc__(self):
if self.c_credentials != NULL: if self.c_credentials != NULL:
grpc.grpc_server_credentials_release(self.c_credentials) grpc_server_credentials_release(self.c_credentials)
cdef class CredentialsMetadataPlugin: cdef class CredentialsMetadataPlugin:
@ -86,8 +83,8 @@ cdef class CredentialsMetadataPlugin:
""" """
Args: Args:
plugin_callback (callable): Callback accepting a service URL (str/bytes) plugin_callback (callable): Callback accepting a service URL (str/bytes)
and callback object (accepting a records.Metadata, and callback object (accepting a Metadata,
grpc.grpc_status_code, and a str/bytes error message). This argument grpc_status_code, and a str/bytes error message). This argument
when called should be non-blocking and eventually call the callback when called should be non-blocking and eventually call the callback
object with the appropriate status code/details and metadata (if object with the appropriate status code/details and metadata (if
successful). successful).
@ -99,8 +96,8 @@ cdef class CredentialsMetadataPlugin:
self.plugin_name = name self.plugin_name = name
@staticmethod @staticmethod
cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self): cdef grpc_metadata_credentials_plugin make_c_plugin(self):
cdef grpc.grpc_metadata_credentials_plugin result cdef grpc_metadata_credentials_plugin result
result.get_metadata = plugin_get_metadata result.get_metadata = plugin_get_metadata
result.destroy = plugin_destroy_c_plugin_state result.destroy = plugin_destroy_c_plugin_state
result.state = <void *>self result.state = <void *>self
@ -125,10 +122,10 @@ cdef class AuthMetadataContext:
cdef void plugin_get_metadata( cdef void plugin_get_metadata(
void *state, grpc.grpc_auth_metadata_context context, void *state, grpc_auth_metadata_context context,
grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil: grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
def python_callback( def python_callback(
records.Metadata metadata, grpc.grpc_status_code status, Metadata metadata, grpc_status_code status,
const char *error_details): const char *error_details):
cb(user_data, metadata.c_metadata_array.metadata, cb(user_data, metadata.c_metadata_array.metadata,
metadata.c_metadata_array.count, status, error_details) metadata.c_metadata_array.count, status, error_details)
@ -142,11 +139,11 @@ cdef void plugin_destroy_c_plugin_state(void *state):
def channel_credentials_google_default(): def channel_credentials_google_default():
cdef ChannelCredentials credentials = ChannelCredentials(); cdef ChannelCredentials credentials = ChannelCredentials();
credentials.c_credentials = grpc.grpc_google_default_credentials_create() credentials.c_credentials = grpc_google_default_credentials_create()
return credentials return credentials
def channel_credentials_ssl(pem_root_certificates, def channel_credentials_ssl(pem_root_certificates,
records.SslPemKeyCertPair ssl_pem_key_cert_pair): SslPemKeyCertPair ssl_pem_key_cert_pair):
if pem_root_certificates is None: if pem_root_certificates is None:
pass pass
elif isinstance(pem_root_certificates, bytes): elif isinstance(pem_root_certificates, bytes):
@ -161,11 +158,11 @@ def channel_credentials_ssl(pem_root_certificates,
c_pem_root_certificates = pem_root_certificates c_pem_root_certificates = pem_root_certificates
credentials.references.append(pem_root_certificates) credentials.references.append(pem_root_certificates)
if ssl_pem_key_cert_pair is not None: if ssl_pem_key_cert_pair is not None:
credentials.c_credentials = grpc.grpc_ssl_credentials_create( credentials.c_credentials = grpc_ssl_credentials_create(
c_pem_root_certificates, &ssl_pem_key_cert_pair.c_pair, NULL) c_pem_root_certificates, &ssl_pem_key_cert_pair.c_pair, NULL)
credentials.references.append(ssl_pem_key_cert_pair) credentials.references.append(ssl_pem_key_cert_pair)
else: else:
credentials.c_credentials = grpc.grpc_ssl_credentials_create( credentials.c_credentials = grpc_ssl_credentials_create(
c_pem_root_certificates, NULL, NULL) c_pem_root_certificates, NULL, NULL)
return credentials return credentials
@ -175,7 +172,7 @@ def channel_credentials_composite(
if not credentials_1.is_valid or not credentials_2.is_valid: if not credentials_1.is_valid or not credentials_2.is_valid:
raise ValueError("passed credentials must both be valid") raise ValueError("passed credentials must both be valid")
cdef ChannelCredentials credentials = ChannelCredentials() cdef ChannelCredentials credentials = ChannelCredentials()
credentials.c_credentials = grpc.grpc_composite_channel_credentials_create( credentials.c_credentials = grpc_composite_channel_credentials_create(
credentials_1.c_credentials, credentials_2.c_credentials, NULL) credentials_1.c_credentials, credentials_2.c_credentials, NULL)
credentials.references.append(credentials_1) credentials.references.append(credentials_1)
credentials.references.append(credentials_2) credentials.references.append(credentials_2)
@ -187,7 +184,7 @@ def call_credentials_composite(
if not credentials_1.is_valid or not credentials_2.is_valid: if not credentials_1.is_valid or not credentials_2.is_valid:
raise ValueError("passed credentials must both be valid") raise ValueError("passed credentials must both be valid")
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = grpc.grpc_composite_call_credentials_create( credentials.c_credentials = grpc_composite_call_credentials_create(
credentials_1.c_credentials, credentials_2.c_credentials, NULL) credentials_1.c_credentials, credentials_2.c_credentials, NULL)
credentials.references.append(credentials_1) credentials.references.append(credentials_1)
credentials.references.append(credentials_2) credentials.references.append(credentials_2)
@ -196,11 +193,11 @@ def call_credentials_composite(
def call_credentials_google_compute_engine(): def call_credentials_google_compute_engine():
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = ( credentials.c_credentials = (
grpc.grpc_google_compute_engine_credentials_create(NULL)) grpc_google_compute_engine_credentials_create(NULL))
return credentials return credentials
def call_credentials_service_account_jwt_access( def call_credentials_service_account_jwt_access(
json_key, records.Timespec token_lifetime not None): json_key, Timespec token_lifetime not None):
if isinstance(json_key, bytes): if isinstance(json_key, bytes):
pass pass
elif isinstance(json_key, basestring): elif isinstance(json_key, basestring):
@ -209,7 +206,7 @@ def call_credentials_service_account_jwt_access(
raise TypeError("expected json_key to be str or bytes") raise TypeError("expected json_key to be str or bytes")
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = ( credentials.c_credentials = (
grpc.grpc_service_account_jwt_access_credentials_create( grpc_service_account_jwt_access_credentials_create(
json_key, token_lifetime.c_time, NULL)) json_key, token_lifetime.c_time, NULL))
credentials.references.append(json_key) credentials.references.append(json_key)
return credentials return credentials
@ -222,7 +219,7 @@ def call_credentials_google_refresh_token(json_refresh_token):
else: else:
raise TypeError("expected json_refresh_token to be str or bytes") raise TypeError("expected json_refresh_token to be str or bytes")
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = grpc.grpc_google_refresh_token_credentials_create( credentials.c_credentials = grpc_google_refresh_token_credentials_create(
json_refresh_token, NULL) json_refresh_token, NULL)
credentials.references.append(json_refresh_token) credentials.references.append(json_refresh_token)
return credentials return credentials
@ -241,7 +238,7 @@ def call_credentials_google_iam(authorization_token, authority_selector):
else: else:
raise TypeError("expected authority_selector to be str or bytes") raise TypeError("expected authority_selector to be str or bytes")
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = grpc.grpc_google_iam_credentials_create( credentials.c_credentials = grpc_google_iam_credentials_create(
authorization_token, authority_selector, NULL) authorization_token, authority_selector, NULL)
credentials.references.append(authorization_token) credentials.references.append(authorization_token)
credentials.references.append(authority_selector) credentials.references.append(authority_selector)
@ -250,7 +247,7 @@ def call_credentials_google_iam(authorization_token, authority_selector):
def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin): def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin):
cdef CallCredentials credentials = CallCredentials() cdef CallCredentials credentials = CallCredentials()
credentials.c_credentials = ( credentials.c_credentials = (
grpc.grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(), grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(),
NULL)) NULL))
# TODO(atash): the following held reference is *probably* never necessary # TODO(atash): the following held reference is *probably* never necessary
credentials.references.append(plugin) credentials.references.append(plugin)
@ -270,22 +267,22 @@ def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
raise TypeError("expected pem_root_certs to be str or bytes") raise TypeError("expected pem_root_certs to be str or bytes")
pem_key_cert_pairs = list(pem_key_cert_pairs) pem_key_cert_pairs = list(pem_key_cert_pairs)
for pair in pem_key_cert_pairs: for pair in pem_key_cert_pairs:
if not isinstance(pair, records.SslPemKeyCertPair): if not isinstance(pair, SslPemKeyCertPair):
raise TypeError("expected pem_key_cert_pairs to be sequence of " raise TypeError("expected pem_key_cert_pairs to be sequence of "
"records.SslPemKeyCertPair") "SslPemKeyCertPair")
cdef ServerCredentials credentials = ServerCredentials() cdef ServerCredentials credentials = ServerCredentials()
credentials.references.append(pem_key_cert_pairs) credentials.references.append(pem_key_cert_pairs)
credentials.references.append(pem_root_certs) credentials.references.append(pem_root_certs)
credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs) credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs)
credentials.c_ssl_pem_key_cert_pairs = ( credentials.c_ssl_pem_key_cert_pairs = (
<grpc.grpc_ssl_pem_key_cert_pair *>grpc.gpr_malloc( <grpc_ssl_pem_key_cert_pair *>gpr_malloc(
sizeof(grpc.grpc_ssl_pem_key_cert_pair) * sizeof(grpc_ssl_pem_key_cert_pair) *
credentials.c_ssl_pem_key_cert_pairs_count credentials.c_ssl_pem_key_cert_pairs_count
)) ))
for i in range(credentials.c_ssl_pem_key_cert_pairs_count): for i in range(credentials.c_ssl_pem_key_cert_pairs_count):
credentials.c_ssl_pem_key_cert_pairs[i] = ( credentials.c_ssl_pem_key_cert_pairs[i] = (
(<records.SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair) (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair)
credentials.c_credentials = grpc.grpc_ssl_server_credentials_create( credentials.c_credentials = grpc_ssl_server_credentials_create(
c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs, c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
credentials.c_ssl_pem_key_cert_pairs_count, force_client_auth, NULL) credentials.c_ssl_pem_key_cert_pairs_count, force_client_auth, NULL)
return credentials return credentials

@ -27,19 +27,15 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport server
cdef class Timespec: cdef class Timespec:
cdef grpc.gpr_timespec c_time cdef gpr_timespec c_time
cdef class CallDetails: cdef class CallDetails:
cdef grpc.grpc_call_details c_details cdef grpc_call_details c_details
cdef class OperationTag: cdef class OperationTag:
@ -48,8 +44,8 @@ cdef class OperationTag:
cdef list references cdef list references
# This allows CompletionQueue to notify the Python Server object that the # This allows CompletionQueue to notify the Python Server object that the
# underlying GRPC core server has shutdown # underlying GRPC core server has shutdown
cdef server.Server shutting_down_server cdef Server shutting_down_server
cdef call.Call operation_call cdef Call operation_call
cdef CallDetails request_call_details cdef CallDetails request_call_details
cdef Metadata request_metadata cdef Metadata request_metadata
cdef Operations batch_operations cdef Operations batch_operations
@ -58,12 +54,12 @@ cdef class OperationTag:
cdef class Event: cdef class Event:
cdef readonly grpc.grpc_completion_type type cdef readonly grpc_completion_type type
cdef readonly bint success cdef readonly bint success
cdef readonly object tag cdef readonly object tag
# For operations with calls # For operations with calls
cdef readonly call.Call operation_call cdef readonly Call operation_call
# For Server.request_call # For Server.request_call
cdef readonly bint is_new_request cdef readonly bint is_new_request
@ -76,45 +72,45 @@ cdef class Event:
cdef class ByteBuffer: cdef class ByteBuffer:
cdef grpc.grpc_byte_buffer *c_byte_buffer cdef grpc_byte_buffer *c_byte_buffer
cdef class SslPemKeyCertPair: cdef class SslPemKeyCertPair:
cdef grpc.grpc_ssl_pem_key_cert_pair c_pair cdef grpc_ssl_pem_key_cert_pair c_pair
cdef readonly object private_key, certificate_chain cdef readonly object private_key, certificate_chain
cdef class ChannelArg: cdef class ChannelArg:
cdef grpc.grpc_arg c_arg cdef grpc_arg c_arg
cdef readonly object key, value cdef readonly object key, value
cdef class ChannelArgs: cdef class ChannelArgs:
cdef grpc.grpc_channel_args c_args cdef grpc_channel_args c_args
cdef list args cdef list args
cdef class Metadatum: cdef class Metadatum:
cdef grpc.grpc_metadata c_metadata cdef grpc_metadata c_metadata
cdef object _key, _value cdef object _key, _value
cdef class Metadata: cdef class Metadata:
cdef grpc.grpc_metadata_array c_metadata_array cdef grpc_metadata_array c_metadata_array
cdef object metadata cdef object metadata
cdef class Operation: cdef class Operation:
cdef grpc.grpc_op c_op cdef grpc_op c_op
cdef ByteBuffer _received_message cdef ByteBuffer _received_message
cdef Metadata _received_metadata cdef Metadata _received_metadata
cdef grpc.grpc_status_code _received_status_code cdef grpc_status_code _received_status_code
cdef char *_received_status_details cdef char *_received_status_details
cdef size_t _received_status_details_capacity cdef size_t _received_status_details_capacity
cdef int _received_cancelled cdef int _received_cancelled
@ -124,7 +120,7 @@ cdef class Operation:
cdef class Operations: cdef class Operations:
cdef grpc.grpc_op *c_ops cdef grpc_op *c_ops
cdef size_t c_nops cdef size_t c_nops
cdef list operations cdef list operations

@ -27,103 +27,99 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport server
class ConnectivityState: class ConnectivityState:
idle = grpc.GRPC_CHANNEL_IDLE idle = GRPC_CHANNEL_IDLE
connecting = grpc.GRPC_CHANNEL_CONNECTING connecting = GRPC_CHANNEL_CONNECTING
ready = grpc.GRPC_CHANNEL_READY ready = GRPC_CHANNEL_READY
transient_failure = grpc.GRPC_CHANNEL_TRANSIENT_FAILURE transient_failure = GRPC_CHANNEL_TRANSIENT_FAILURE
fatal_failure = grpc.GRPC_CHANNEL_FATAL_FAILURE fatal_failure = GRPC_CHANNEL_FATAL_FAILURE
class ChannelArgKey: class ChannelArgKey:
enable_census = grpc.GRPC_ARG_ENABLE_CENSUS enable_census = GRPC_ARG_ENABLE_CENSUS
max_concurrent_streams = grpc.GRPC_ARG_MAX_CONCURRENT_STREAMS max_concurrent_streams = GRPC_ARG_MAX_CONCURRENT_STREAMS
max_message_length = grpc.GRPC_ARG_MAX_MESSAGE_LENGTH max_message_length = GRPC_ARG_MAX_MESSAGE_LENGTH
http2_initial_sequence_number = grpc.GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER http2_initial_sequence_number = GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER
default_authority = grpc.GRPC_ARG_DEFAULT_AUTHORITY default_authority = GRPC_ARG_DEFAULT_AUTHORITY
primary_user_agent_string = grpc.GRPC_ARG_PRIMARY_USER_AGENT_STRING primary_user_agent_string = GRPC_ARG_PRIMARY_USER_AGENT_STRING
secondary_user_agent_string = grpc.GRPC_ARG_SECONDARY_USER_AGENT_STRING secondary_user_agent_string = GRPC_ARG_SECONDARY_USER_AGENT_STRING
ssl_target_name_override = grpc.GRPC_SSL_TARGET_NAME_OVERRIDE_ARG ssl_target_name_override = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
class WriteFlag: class WriteFlag:
buffer_hint = grpc.GRPC_WRITE_BUFFER_HINT buffer_hint = GRPC_WRITE_BUFFER_HINT
no_compress = grpc.GRPC_WRITE_NO_COMPRESS no_compress = GRPC_WRITE_NO_COMPRESS
class StatusCode: class StatusCode:
ok = grpc.GRPC_STATUS_OK ok = GRPC_STATUS_OK
cancelled = grpc.GRPC_STATUS_CANCELLED cancelled = GRPC_STATUS_CANCELLED
unknown = grpc.GRPC_STATUS_UNKNOWN unknown = GRPC_STATUS_UNKNOWN
invalid_argument = grpc.GRPC_STATUS_INVALID_ARGUMENT invalid_argument = GRPC_STATUS_INVALID_ARGUMENT
deadline_exceeded = grpc.GRPC_STATUS_DEADLINE_EXCEEDED deadline_exceeded = GRPC_STATUS_DEADLINE_EXCEEDED
not_found = grpc.GRPC_STATUS_NOT_FOUND not_found = GRPC_STATUS_NOT_FOUND
already_exists = grpc.GRPC_STATUS_ALREADY_EXISTS already_exists = GRPC_STATUS_ALREADY_EXISTS
permission_denied = grpc.GRPC_STATUS_PERMISSION_DENIED permission_denied = GRPC_STATUS_PERMISSION_DENIED
unauthenticated = grpc.GRPC_STATUS_UNAUTHENTICATED unauthenticated = GRPC_STATUS_UNAUTHENTICATED
resource_exhausted = grpc.GRPC_STATUS_RESOURCE_EXHAUSTED resource_exhausted = GRPC_STATUS_RESOURCE_EXHAUSTED
failed_precondition = grpc.GRPC_STATUS_FAILED_PRECONDITION failed_precondition = GRPC_STATUS_FAILED_PRECONDITION
aborted = grpc.GRPC_STATUS_ABORTED aborted = GRPC_STATUS_ABORTED
out_of_range = grpc.GRPC_STATUS_OUT_OF_RANGE out_of_range = GRPC_STATUS_OUT_OF_RANGE
unimplemented = grpc.GRPC_STATUS_UNIMPLEMENTED unimplemented = GRPC_STATUS_UNIMPLEMENTED
internal = grpc.GRPC_STATUS_INTERNAL internal = GRPC_STATUS_INTERNAL
unavailable = grpc.GRPC_STATUS_UNAVAILABLE unavailable = GRPC_STATUS_UNAVAILABLE
data_loss = grpc.GRPC_STATUS_DATA_LOSS data_loss = GRPC_STATUS_DATA_LOSS
class CallError: class CallError:
ok = grpc.GRPC_CALL_OK ok = GRPC_CALL_OK
error = grpc.GRPC_CALL_ERROR error = GRPC_CALL_ERROR
not_on_server = grpc.GRPC_CALL_ERROR_NOT_ON_SERVER not_on_server = GRPC_CALL_ERROR_NOT_ON_SERVER
not_on_client = grpc.GRPC_CALL_ERROR_NOT_ON_CLIENT not_on_client = GRPC_CALL_ERROR_NOT_ON_CLIENT
already_accepted = grpc.GRPC_CALL_ERROR_ALREADY_ACCEPTED already_accepted = GRPC_CALL_ERROR_ALREADY_ACCEPTED
already_invoked = grpc.GRPC_CALL_ERROR_ALREADY_INVOKED already_invoked = GRPC_CALL_ERROR_ALREADY_INVOKED
not_invoked = grpc.GRPC_CALL_ERROR_NOT_INVOKED not_invoked = GRPC_CALL_ERROR_NOT_INVOKED
already_finished = grpc.GRPC_CALL_ERROR_ALREADY_FINISHED already_finished = GRPC_CALL_ERROR_ALREADY_FINISHED
too_many_operations = grpc.GRPC_CALL_ERROR_TOO_MANY_OPERATIONS too_many_operations = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS
invalid_flags = grpc.GRPC_CALL_ERROR_INVALID_FLAGS invalid_flags = GRPC_CALL_ERROR_INVALID_FLAGS
invalid_metadata = grpc.GRPC_CALL_ERROR_INVALID_METADATA invalid_metadata = GRPC_CALL_ERROR_INVALID_METADATA
class CompletionType: class CompletionType:
queue_shutdown = grpc.GRPC_QUEUE_SHUTDOWN queue_shutdown = GRPC_QUEUE_SHUTDOWN
queue_timeout = grpc.GRPC_QUEUE_TIMEOUT queue_timeout = GRPC_QUEUE_TIMEOUT
operation_complete = grpc.GRPC_OP_COMPLETE operation_complete = GRPC_OP_COMPLETE
class OperationType: class OperationType:
send_initial_metadata = grpc.GRPC_OP_SEND_INITIAL_METADATA send_initial_metadata = GRPC_OP_SEND_INITIAL_METADATA
send_message = grpc.GRPC_OP_SEND_MESSAGE send_message = GRPC_OP_SEND_MESSAGE
send_close_from_client = grpc.GRPC_OP_SEND_CLOSE_FROM_CLIENT send_close_from_client = GRPC_OP_SEND_CLOSE_FROM_CLIENT
send_status_from_server = grpc.GRPC_OP_SEND_STATUS_FROM_SERVER send_status_from_server = GRPC_OP_SEND_STATUS_FROM_SERVER
receive_initial_metadata = grpc.GRPC_OP_RECV_INITIAL_METADATA receive_initial_metadata = GRPC_OP_RECV_INITIAL_METADATA
receive_message = grpc.GRPC_OP_RECV_MESSAGE receive_message = GRPC_OP_RECV_MESSAGE
receive_status_on_client = grpc.GRPC_OP_RECV_STATUS_ON_CLIENT receive_status_on_client = GRPC_OP_RECV_STATUS_ON_CLIENT
receive_close_on_server = grpc.GRPC_OP_RECV_CLOSE_ON_SERVER receive_close_on_server = GRPC_OP_RECV_CLOSE_ON_SERVER
cdef class Timespec: cdef class Timespec:
def __cinit__(self, time): def __cinit__(self, time):
if time is None: if time is None:
self.c_time = grpc.gpr_now(grpc.GPR_CLOCK_REALTIME) self.c_time = gpr_now(GPR_CLOCK_REALTIME)
return return
if isinstance(time, int): if isinstance(time, int):
time = float(time) time = float(time)
if isinstance(time, float): if isinstance(time, float):
if time == float("+inf"): if time == float("+inf"):
self.c_time = grpc.gpr_inf_future(grpc.GPR_CLOCK_REALTIME) self.c_time = gpr_inf_future(GPR_CLOCK_REALTIME)
elif time == float("-inf"): elif time == float("-inf"):
self.c_time = grpc.gpr_inf_past(grpc.GPR_CLOCK_REALTIME) self.c_time = gpr_inf_past(GPR_CLOCK_REALTIME)
else: else:
self.c_time.seconds = time self.c_time.seconds = time
self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9 self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9
self.c_time.clock_type = grpc.GPR_CLOCK_REALTIME self.c_time.clock_type = GPR_CLOCK_REALTIME
elif isinstance(time, Timespec): elif isinstance(time, Timespec):
self.c_time = (<Timespec>time).c_time self.c_time = (<Timespec>time).c_time
else: else:
@ -135,19 +131,19 @@ cdef class Timespec:
# TODO(atash) ensure that everywhere a Timespec is created that it's # TODO(atash) ensure that everywhere a Timespec is created that it's
# converted to GPR_CLOCK_REALTIME then and not every time someone wants to # converted to GPR_CLOCK_REALTIME then and not every time someone wants to
# read values off in Python. # read values off in Python.
cdef grpc.gpr_timespec real_time = ( cdef gpr_timespec real_time = (
grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
return real_time.seconds return real_time.seconds
@property @property
def nanoseconds(self): def nanoseconds(self):
cdef grpc.gpr_timespec real_time = ( cdef gpr_timespec real_time = (
grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
return real_time.nanoseconds return real_time.nanoseconds
def __float__(self): def __float__(self):
cdef grpc.gpr_timespec real_time = ( cdef gpr_timespec real_time = (
grpc.gpr_convert_clock_type(self.c_time, grpc.GPR_CLOCK_REALTIME)) gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
return <double>real_time.seconds + <double>real_time.nanoseconds / 1e9 return <double>real_time.seconds + <double>real_time.nanoseconds / 1e9
infinite_future = Timespec(float("+inf")) infinite_future = Timespec(float("+inf"))
@ -157,10 +153,10 @@ cdef class Timespec:
cdef class CallDetails: cdef class CallDetails:
def __cinit__(self): def __cinit__(self):
grpc.grpc_call_details_init(&self.c_details) grpc_call_details_init(&self.c_details)
def __dealloc__(self): def __dealloc__(self):
grpc.grpc_call_details_destroy(&self.c_details) grpc_call_details_destroy(&self.c_details)
@property @property
def method(self): def method(self):
@ -192,8 +188,8 @@ cdef class OperationTag:
cdef class Event: cdef class Event:
def __cinit__(self, grpc.grpc_completion_type type, bint success, def __cinit__(self, grpc_completion_type type, bint success,
object tag, call.Call operation_call, object tag, Call operation_call,
CallDetails request_call_details, CallDetails request_call_details,
Metadata request_metadata, Metadata request_metadata,
bint is_new_request, bint is_new_request,
@ -228,31 +224,31 @@ cdef class ByteBuffer:
"ByteBuffer, not {}".format(type(data))) "ByteBuffer, not {}".format(type(data)))
cdef char *c_data = data cdef char *c_data = data
data_slice = grpc.gpr_slice_from_copied_buffer(c_data, len(data)) data_slice = gpr_slice_from_copied_buffer(c_data, len(data))
self.c_byte_buffer = grpc.grpc_raw_byte_buffer_create( self.c_byte_buffer = grpc_raw_byte_buffer_create(
&data_slice, 1) &data_slice, 1)
grpc.gpr_slice_unref(data_slice) gpr_slice_unref(data_slice)
def bytes(self): def bytes(self):
cdef grpc.grpc_byte_buffer_reader reader cdef grpc_byte_buffer_reader reader
cdef grpc.gpr_slice data_slice cdef gpr_slice data_slice
cdef size_t data_slice_length cdef size_t data_slice_length
cdef void *data_slice_pointer cdef void *data_slice_pointer
if self.c_byte_buffer != NULL: if self.c_byte_buffer != NULL:
grpc.grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer) grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer)
result = b"" result = b""
while grpc.grpc_byte_buffer_reader_next(&reader, &data_slice): while grpc_byte_buffer_reader_next(&reader, &data_slice):
data_slice_pointer = grpc.gpr_slice_start_ptr(data_slice) data_slice_pointer = gpr_slice_start_ptr(data_slice)
data_slice_length = grpc.gpr_slice_length(data_slice) data_slice_length = gpr_slice_length(data_slice)
result += (<char *>data_slice_pointer)[:data_slice_length] result += (<char *>data_slice_pointer)[:data_slice_length]
grpc.grpc_byte_buffer_reader_destroy(&reader) grpc_byte_buffer_reader_destroy(&reader)
return result return result
else: else:
return None return None
def __len__(self): def __len__(self):
if self.c_byte_buffer != NULL: if self.c_byte_buffer != NULL:
return grpc.grpc_byte_buffer_length(self.c_byte_buffer) return grpc_byte_buffer_length(self.c_byte_buffer)
else: else:
return 0 return 0
@ -261,7 +257,7 @@ cdef class ByteBuffer:
def __dealloc__(self): def __dealloc__(self):
if self.c_byte_buffer != NULL: if self.c_byte_buffer != NULL:
grpc.grpc_byte_buffer_destroy(self.c_byte_buffer) grpc_byte_buffer_destroy(self.c_byte_buffer)
cdef class SslPemKeyCertPair: cdef class SslPemKeyCertPair:
@ -295,15 +291,15 @@ cdef class ChannelArg:
raise TypeError("expected key to be of type str or bytes") raise TypeError("expected key to be of type str or bytes")
if isinstance(value, bytes): if isinstance(value, bytes):
self.value = value self.value = value
self.c_arg.type = grpc.GRPC_ARG_STRING self.c_arg.type = GRPC_ARG_STRING
self.c_arg.value.string = self.value self.c_arg.value.string = self.value
elif isinstance(value, basestring): elif isinstance(value, basestring):
self.value = value.encode() self.value = value.encode()
self.c_arg.type = grpc.GRPC_ARG_STRING self.c_arg.type = GRPC_ARG_STRING
self.c_arg.value.string = self.value self.c_arg.value.string = self.value
elif isinstance(value, int): elif isinstance(value, int):
self.value = int(value) self.value = int(value)
self.c_arg.type = grpc.GRPC_ARG_INTEGER self.c_arg.type = GRPC_ARG_INTEGER
self.c_arg.value.integer = self.value self.c_arg.value.integer = self.value
else: else:
raise TypeError("expected value to be of type str or bytes or int") raise TypeError("expected value to be of type str or bytes or int")
@ -318,14 +314,14 @@ cdef class ChannelArgs:
if not isinstance(arg, ChannelArg): if not isinstance(arg, ChannelArg):
raise TypeError("expected list of ChannelArg") raise TypeError("expected list of ChannelArg")
self.c_args.arguments_length = len(self.args) self.c_args.arguments_length = len(self.args)
self.c_args.arguments = <grpc.grpc_arg *>grpc.gpr_malloc( self.c_args.arguments = <grpc_arg *>gpr_malloc(
self.c_args.arguments_length*sizeof(grpc.grpc_arg) self.c_args.arguments_length*sizeof(grpc_arg)
) )
for i in range(self.c_args.arguments_length): for i in range(self.c_args.arguments_length):
self.c_args.arguments[i] = (<ChannelArg>self.args[i]).c_arg self.c_args.arguments[i] = (<ChannelArg>self.args[i]).c_arg
def __dealloc__(self): def __dealloc__(self):
grpc.gpr_free(self.c_args.arguments) gpr_free(self.c_args.arguments)
def __len__(self): def __len__(self):
# self.args is never stale; it's only updated from this file # self.args is never stale; it's only updated from this file
@ -406,11 +402,11 @@ cdef class Metadata:
for metadatum in metadata: for metadatum in metadata:
if not isinstance(metadatum, Metadatum): if not isinstance(metadatum, Metadatum):
raise TypeError("expected list of Metadatum") raise TypeError("expected list of Metadatum")
grpc.grpc_metadata_array_init(&self.c_metadata_array) grpc_metadata_array_init(&self.c_metadata_array)
self.c_metadata_array.count = len(self.metadata) self.c_metadata_array.count = len(self.metadata)
self.c_metadata_array.capacity = len(self.metadata) self.c_metadata_array.capacity = len(self.metadata)
self.c_metadata_array.metadata = <grpc.grpc_metadata *>grpc.gpr_malloc( self.c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
self.c_metadata_array.count*sizeof(grpc.grpc_metadata) self.c_metadata_array.count*sizeof(grpc_metadata)
) )
for i in range(self.c_metadata_array.count): for i in range(self.c_metadata_array.count):
self.c_metadata_array.metadata[i] = ( self.c_metadata_array.metadata[i] = (
@ -420,7 +416,7 @@ cdef class Metadata:
# this frees the allocated memory for the grpc_metadata_array (although # this frees the allocated memory for the grpc_metadata_array (although
# it'd be nice if that were documented somewhere...) TODO(atash): document # it'd be nice if that were documented somewhere...) TODO(atash): document
# this in the C core # this in the C core
grpc.grpc_metadata_array_destroy(&self.c_metadata_array) grpc_metadata_array_destroy(&self.c_metadata_array)
def __len__(self): def __len__(self):
return self.c_metadata_array.count return self.c_metadata_array.count
@ -449,49 +445,49 @@ cdef class Operation:
@property @property
def has_status(self): def has_status(self):
return self.c_op.type == grpc.GRPC_OP_RECV_STATUS_ON_CLIENT return self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT
@property @property
def received_message(self): def received_message(self):
if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE: if self.c_op.type != GRPC_OP_RECV_MESSAGE:
raise TypeError("self must be an operation receiving a message") raise TypeError("self must be an operation receiving a message")
return self._received_message return self._received_message
@property @property
def received_message_or_none(self): def received_message_or_none(self):
if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE: if self.c_op.type != GRPC_OP_RECV_MESSAGE:
return None return None
return self._received_message return self._received_message
@property @property
def received_metadata(self): def received_metadata(self):
if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and
self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT): self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT):
raise TypeError("self must be an operation receiving metadata") raise TypeError("self must be an operation receiving metadata")
return self._received_metadata return self._received_metadata
@property @property
def received_metadata_or_none(self): def received_metadata_or_none(self):
if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and
self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT): self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT):
return None return None
return self._received_metadata return self._received_metadata
@property @property
def received_status_code(self): def received_status_code(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
raise TypeError("self must be an operation receiving a status code") raise TypeError("self must be an operation receiving a status code")
return self._received_status_code return self._received_status_code
@property @property
def received_status_code_or_none(self): def received_status_code_or_none(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
return None return None
return self._received_status_code return self._received_status_code
@property @property
def received_status_details(self): def received_status_details(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
raise TypeError("self must be an operation receiving status details") raise TypeError("self must be an operation receiving status details")
if self._received_status_details: if self._received_status_details:
return self._received_status_details return self._received_status_details
@ -500,7 +496,7 @@ cdef class Operation:
@property @property
def received_status_details_or_none(self): def received_status_details_or_none(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: if self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT:
return None return None
if self._received_status_details: if self._received_status_details:
return self._received_status_details return self._received_status_details
@ -509,14 +505,14 @@ cdef class Operation:
@property @property
def received_cancelled(self): def received_cancelled(self):
if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER: if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER:
raise TypeError("self must be an operation receiving cancellation " raise TypeError("self must be an operation receiving cancellation "
"information") "information")
return False if self._received_cancelled == 0 else True return False if self._received_cancelled == 0 else True
@property @property
def received_cancelled_or_none(self): def received_cancelled_or_none(self):
if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER: if self.c_op.type != GRPC_OP_RECV_CLOSE_ON_SERVER:
return None return None
return False if self._received_cancelled == 0 else True return False if self._received_cancelled == 0 else True
@ -524,12 +520,12 @@ cdef class Operation:
# We *almost* don't need to do anything; most of the objects are handled by # We *almost* don't need to do anything; most of the objects are handled by
# Python. The remaining one(s) are primitive fields filled in by GRPC core. # Python. The remaining one(s) are primitive fields filled in by GRPC core.
# This means that we need to clean up after receive_status_on_client. # This means that we need to clean up after receive_status_on_client.
if self.c_op.type == grpc.GRPC_OP_RECV_STATUS_ON_CLIENT: if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT:
grpc.gpr_free(self._received_status_details) gpr_free(self._received_status_details)
def operation_send_initial_metadata(Metadata metadata): def operation_send_initial_metadata(Metadata metadata):
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_SEND_INITIAL_METADATA op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA
op.c_op.data.send_initial_metadata.count = metadata.c_metadata_array.count op.c_op.data.send_initial_metadata.count = metadata.c_metadata_array.count
op.c_op.data.send_initial_metadata.metadata = ( op.c_op.data.send_initial_metadata.metadata = (
metadata.c_metadata_array.metadata) metadata.c_metadata_array.metadata)
@ -539,7 +535,7 @@ def operation_send_initial_metadata(Metadata metadata):
def operation_send_message(data): def operation_send_message(data):
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_SEND_MESSAGE op.c_op.type = GRPC_OP_SEND_MESSAGE
byte_buffer = ByteBuffer(data) byte_buffer = ByteBuffer(data)
op.c_op.data.send_message = byte_buffer.c_byte_buffer op.c_op.data.send_message = byte_buffer.c_byte_buffer
op.references.append(byte_buffer) op.references.append(byte_buffer)
@ -548,12 +544,12 @@ def operation_send_message(data):
def operation_send_close_from_client(): def operation_send_close_from_client():
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_SEND_CLOSE_FROM_CLIENT op.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT
op.is_valid = True op.is_valid = True
return op return op
def operation_send_status_from_server( def operation_send_status_from_server(
Metadata metadata, grpc.grpc_status_code code, details): Metadata metadata, grpc_status_code code, details):
if isinstance(details, bytes): if isinstance(details, bytes):
pass pass
elif isinstance(details, basestring): elif isinstance(details, basestring):
@ -561,7 +557,7 @@ def operation_send_status_from_server(
else: else:
raise TypeError("expected a str or bytes object for details") raise TypeError("expected a str or bytes object for details")
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_SEND_STATUS_FROM_SERVER op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
op.c_op.data.send_status_from_server.trailing_metadata_count = ( op.c_op.data.send_status_from_server.trailing_metadata_count = (
metadata.c_metadata_array.count) metadata.c_metadata_array.count)
op.c_op.data.send_status_from_server.trailing_metadata = ( op.c_op.data.send_status_from_server.trailing_metadata = (
@ -575,7 +571,7 @@ def operation_send_status_from_server(
def operation_receive_initial_metadata(): def operation_receive_initial_metadata():
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_RECV_INITIAL_METADATA op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA
op._received_metadata = Metadata([]) op._received_metadata = Metadata([])
op.c_op.data.receive_initial_metadata = ( op.c_op.data.receive_initial_metadata = (
&op._received_metadata.c_metadata_array) &op._received_metadata.c_metadata_array)
@ -584,7 +580,7 @@ def operation_receive_initial_metadata():
def operation_receive_message(): def operation_receive_message():
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_RECV_MESSAGE op.c_op.type = GRPC_OP_RECV_MESSAGE
op._received_message = ByteBuffer(None) op._received_message = ByteBuffer(None)
# n.b. the c_op.data.receive_message field needs to be deleted by us, # n.b. the c_op.data.receive_message field needs to be deleted by us,
# anyway, so we just let that be handled by the ByteBuffer() we allocated # anyway, so we just let that be handled by the ByteBuffer() we allocated
@ -595,7 +591,7 @@ def operation_receive_message():
def operation_receive_status_on_client(): def operation_receive_status_on_client():
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_RECV_STATUS_ON_CLIENT op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT
op._received_metadata = Metadata([]) op._received_metadata = Metadata([])
op.c_op.data.receive_status_on_client.trailing_metadata = ( op.c_op.data.receive_status_on_client.trailing_metadata = (
&op._received_metadata.c_metadata_array) &op._received_metadata.c_metadata_array)
@ -610,7 +606,7 @@ def operation_receive_status_on_client():
def operation_receive_close_on_server(): def operation_receive_close_on_server():
cdef Operation op = Operation() cdef Operation op = Operation()
op.c_op.type = grpc.GRPC_OP_RECV_CLOSE_ON_SERVER op.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER
op.c_op.data.receive_close_on_server.cancelled = &op._received_cancelled op.c_op.data.receive_close_on_server.cancelled = &op._received_cancelled
op.is_valid = True op.is_valid = True
return op return op
@ -647,8 +643,8 @@ cdef class Operations:
if not isinstance(operation, Operation): if not isinstance(operation, Operation):
raise TypeError("expected operations to be iterable of Operation") raise TypeError("expected operations to be iterable of Operation")
self.c_nops = len(self.operations) self.c_nops = len(self.operations)
self.c_ops = <grpc.grpc_op *>grpc.gpr_malloc( self.c_ops = <grpc_op *>gpr_malloc(
sizeof(grpc.grpc_op)*self.c_nops) sizeof(grpc_op)*self.c_nops)
for i in range(self.c_nops): for i in range(self.c_nops):
self.c_ops[i] = (<Operation>(self.operations[i])).c_op self.c_ops[i] = (<Operation>(self.operations[i])).c_op
@ -660,7 +656,7 @@ cdef class Operations:
return self.operations[i] return self.operations[i]
def __dealloc__(self): def __dealloc__(self):
grpc.gpr_free(self.c_ops) gpr_free(self.c_ops)
def __iter__(self): def __iter__(self):
return _OperationsIterator(self) return _OperationsIterator(self)

@ -27,18 +27,15 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport completion_queue
cdef class Server: cdef class Server:
cdef grpc.grpc_server *c_server cdef grpc_server *c_server
cdef bint is_started # start has been called cdef bint is_started # start has been called
cdef bint is_shutting_down # shutdown has been called cdef bint is_shutting_down # shutdown has been called
cdef bint is_shutdown # notification of complete shutdown received cdef bint is_shutdown # notification of complete shutdown received
# used at dealloc when user forgets to shutdown # used at dealloc when user forgets to shutdown
cdef completion_queue.CompletionQueue backup_shutdown_queue cdef CompletionQueue backup_shutdown_queue
cdef list references cdef list references
cdef list registered_completion_queues cdef list registered_completion_queues

@ -29,45 +29,39 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport completion_queue
from grpc._cython._cygrpc cimport credentials
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
import time import time
cdef class Server: cdef class Server:
def __cinit__(self, records.ChannelArgs arguments=None): def __cinit__(self, ChannelArgs arguments=None):
cdef grpc.grpc_channel_args *c_arguments = NULL cdef grpc_channel_args *c_arguments = NULL
self.references = [] self.references = []
self.registered_completion_queues = [] self.registered_completion_queues = []
if arguments is not None: if arguments is not None:
c_arguments = &arguments.c_args c_arguments = &arguments.c_args
self.references.append(arguments) self.references.append(arguments)
self.c_server = grpc.grpc_server_create(c_arguments, NULL) self.c_server = grpc_server_create(c_arguments, NULL)
self.is_started = False self.is_started = False
self.is_shutting_down = False self.is_shutting_down = False
self.is_shutdown = False self.is_shutdown = False
def request_call( def request_call(
self, completion_queue.CompletionQueue call_queue not None, self, CompletionQueue call_queue not None,
completion_queue.CompletionQueue server_queue not None, tag): CompletionQueue server_queue not None, tag):
if not self.is_started or self.is_shutting_down: if not self.is_started or self.is_shutting_down:
raise ValueError("server must be started and not shutting down") raise ValueError("server must be started and not shutting down")
if server_queue not in self.registered_completion_queues: if server_queue not in self.registered_completion_queues:
raise ValueError("server_queue must be a registered completion queue") raise ValueError("server_queue must be a registered completion queue")
cdef records.OperationTag operation_tag = records.OperationTag(tag) cdef OperationTag operation_tag = OperationTag(tag)
operation_tag.operation_call = call.Call() operation_tag.operation_call = Call()
operation_tag.request_call_details = records.CallDetails() operation_tag.request_call_details = CallDetails()
operation_tag.request_metadata = records.Metadata([]) operation_tag.request_metadata = Metadata([])
operation_tag.references.extend([self, call_queue, server_queue]) operation_tag.references.extend([self, call_queue, server_queue])
operation_tag.is_new_request = True operation_tag.is_new_request = True
operation_tag.batch_operations = records.Operations([]) operation_tag.batch_operations = Operations([])
cpython.Py_INCREF(operation_tag) cpython.Py_INCREF(operation_tag)
return grpc.grpc_server_request_call( return grpc_server_request_call(
self.c_server, &operation_tag.operation_call.c_call, self.c_server, &operation_tag.operation_call.c_call,
&operation_tag.request_call_details.c_details, &operation_tag.request_call_details.c_details,
&operation_tag.request_metadata.c_metadata_array, &operation_tag.request_metadata.c_metadata_array,
@ -75,25 +69,25 @@ cdef class Server:
<cpython.PyObject *>operation_tag) <cpython.PyObject *>operation_tag)
def register_completion_queue( def register_completion_queue(
self, completion_queue.CompletionQueue queue not None): self, CompletionQueue queue not None):
if self.is_started: if self.is_started:
raise ValueError("cannot register completion queues after start") raise ValueError("cannot register completion queues after start")
grpc.grpc_server_register_completion_queue( grpc_server_register_completion_queue(
self.c_server, queue.c_completion_queue, NULL) self.c_server, queue.c_completion_queue, NULL)
self.registered_completion_queues.append(queue) self.registered_completion_queues.append(queue)
def start(self): def start(self):
if self.is_started: if self.is_started:
raise ValueError("the server has already started") raise ValueError("the server has already started")
self.backup_shutdown_queue = completion_queue.CompletionQueue() self.backup_shutdown_queue = CompletionQueue()
self.register_completion_queue(self.backup_shutdown_queue) self.register_completion_queue(self.backup_shutdown_queue)
self.is_started = True self.is_started = True
grpc.grpc_server_start(self.c_server) grpc_server_start(self.c_server)
# Ensure the core has gotten a chance to do the start-up work # Ensure the core has gotten a chance to do the start-up work
self.backup_shutdown_queue.pluck(None, records.Timespec(None)) self.backup_shutdown_queue.pluck(None, Timespec(None))
def add_http2_port(self, address, def add_http2_port(self, address,
credentials.ServerCredentials server_credentials=None): ServerCredentials server_credentials=None):
if isinstance(address, bytes): if isinstance(address, bytes):
pass pass
elif isinstance(address, basestring): elif isinstance(address, basestring):
@ -103,13 +97,13 @@ cdef class Server:
self.references.append(address) self.references.append(address)
if server_credentials is not None: if server_credentials is not None:
self.references.append(server_credentials) self.references.append(server_credentials)
return grpc.grpc_server_add_secure_http2_port( return grpc_server_add_secure_http2_port(
self.c_server, address, server_credentials.c_credentials) self.c_server, address, server_credentials.c_credentials)
else: else:
return grpc.grpc_server_add_insecure_http2_port(self.c_server, address) return grpc_server_add_insecure_http2_port(self.c_server, address)
def shutdown(self, completion_queue.CompletionQueue queue not None, tag): def shutdown(self, CompletionQueue queue not None, tag):
cdef records.OperationTag operation_tag cdef OperationTag operation_tag
if queue.is_shutting_down: if queue.is_shutting_down:
raise ValueError("queue must be live") raise ValueError("queue must be live")
elif not self.is_started: elif not self.is_started:
@ -120,11 +114,11 @@ cdef class Server:
raise ValueError("expected registered completion queue") raise ValueError("expected registered completion queue")
else: else:
self.is_shutting_down = True self.is_shutting_down = True
operation_tag = records.OperationTag(tag) operation_tag = OperationTag(tag)
operation_tag.shutting_down_server = self operation_tag.shutting_down_server = self
operation_tag.references.extend([self, queue]) operation_tag.references.extend([self, queue])
cpython.Py_INCREF(operation_tag) cpython.Py_INCREF(operation_tag)
grpc.grpc_server_shutdown_and_notify( grpc_server_shutdown_and_notify(
self.c_server, queue.c_completion_queue, self.c_server, queue.c_completion_queue,
<cpython.PyObject *>operation_tag) <cpython.PyObject *>operation_tag)
@ -138,7 +132,7 @@ cdef class Server:
elif self.is_shutdown: elif self.is_shutdown:
return return
else: else:
grpc.grpc_server_cancel_all_calls(self.c_server) grpc_server_cancel_all_calls(self.c_server)
def __dealloc__(self): def __dealloc__(self):
if self.c_server != NULL: if self.c_server != NULL:
@ -157,5 +151,5 @@ cdef class Server:
# much but repeatedly release the GIL and wait # much but repeatedly release the GIL and wait
while not self.is_shutdown: while not self.is_shutdown:
time.sleep(0) time.sleep(0)
grpc.grpc_server_destroy(self.c_server) grpc_server_destroy(self.c_server)

@ -0,0 +1,8 @@
include "grpc/_cython/_cygrpc/grpc.pxi"
include "grpc/_cython/_cygrpc/call.pxd.pxi"
include "grpc/_cython/_cygrpc/channel.pxd.pxi"
include "grpc/_cython/_cygrpc/credentials.pxd.pxi"
include "grpc/_cython/_cygrpc/completion_queue.pxd.pxi"
include "grpc/_cython/_cygrpc/records.pxd.pxi"
include "grpc/_cython/_cygrpc/server.pxd.pxi"

@ -29,78 +29,14 @@
cimport cpython cimport cpython
from grpc._cython._cygrpc cimport grpc # TODO(atash): figure out why the coverage tool gets confused about the Cython
from grpc._cython._cygrpc cimport call # coverage plugin when the following files don't have a '.pxi' suffix.
from grpc._cython._cygrpc cimport channel include "grpc/_cython/_cygrpc/call.pyx.pxi"
from grpc._cython._cygrpc cimport credentials include "grpc/_cython/_cygrpc/channel.pyx.pxi"
from grpc._cython._cygrpc cimport completion_queue include "grpc/_cython/_cygrpc/credentials.pyx.pxi"
from grpc._cython._cygrpc cimport records include "grpc/_cython/_cygrpc/completion_queue.pyx.pxi"
from grpc._cython._cygrpc cimport server include "grpc/_cython/_cygrpc/records.pyx.pxi"
include "grpc/_cython/_cygrpc/server.pyx.pxi"
from grpc._cython._cygrpc import call
from grpc._cython._cygrpc import channel
from grpc._cython._cygrpc import credentials
from grpc._cython._cygrpc import completion_queue
from grpc._cython._cygrpc import records
from grpc._cython._cygrpc import server
ConnectivityState = records.ConnectivityState
ChannelArgKey = records.ChannelArgKey
WriteFlag = records.WriteFlag
StatusCode = records.StatusCode
CallError = records.CallError
CompletionType = records.CompletionType
OperationType = records.OperationType
Timespec = records.Timespec
CallDetails = records.CallDetails
Event = records.Event
ByteBuffer = records.ByteBuffer
SslPemKeyCertPair = records.SslPemKeyCertPair
ChannelArg = records.ChannelArg
ChannelArgs = records.ChannelArgs
Metadatum = records.Metadatum
Metadata = records.Metadata
Operation = records.Operation
operation_send_initial_metadata = records.operation_send_initial_metadata
operation_send_message = records.operation_send_message
operation_send_close_from_client = records.operation_send_close_from_client
operation_send_status_from_server = records.operation_send_status_from_server
operation_receive_initial_metadata = records.operation_receive_initial_metadata
operation_receive_message = records.operation_receive_message
operation_receive_status_on_client = records.operation_receive_status_on_client
operation_receive_close_on_server = records.operation_receive_close_on_server
Operations = records.Operations
CallCredentials = credentials.CallCredentials
ChannelCredentials = credentials.ChannelCredentials
ServerCredentials = credentials.ServerCredentials
CredentialsMetadataPlugin = credentials.CredentialsMetadataPlugin
AuthMetadataContext = credentials.AuthMetadataContext
channel_credentials_google_default = (
credentials.channel_credentials_google_default)
channel_credentials_ssl = credentials.channel_credentials_ssl
channel_credentials_composite = (
credentials.channel_credentials_composite)
call_credentials_composite = (
credentials.call_credentials_composite)
call_credentials_google_compute_engine = (
credentials.call_credentials_google_compute_engine)
call_credentials_jwt_access = (
credentials.call_credentials_service_account_jwt_access)
call_credentials_refresh_token = (
credentials.call_credentials_google_refresh_token)
call_credentials_google_iam = credentials.call_credentials_google_iam
call_credentials_metadata_plugin = credentials.call_credentials_metadata_plugin
server_credentials_ssl = credentials.server_credentials_ssl
CompletionQueue = completion_queue.CompletionQueue
Channel = channel.Channel
Server = server.Server
Call = call.Call
# #
# Global state # Global state
@ -109,10 +45,10 @@ Call = call.Call
cdef class _ModuleState: cdef class _ModuleState:
def __cinit__(self): def __cinit__(self):
grpc.grpc_init() grpc_init()
def __dealloc__(self): def __dealloc__(self):
grpc.grpc_shutdown() grpc_shutdown()
_module_state = _ModuleState() _module_state = _ModuleState()

@ -0,0 +1,195 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!!
CORE_SOURCE_FILES = [
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
'src/core/support/avl.c',
'src/core/support/cmdline.c',
'src/core/support/cpu_iphone.c',
'src/core/support/cpu_linux.c',
'src/core/support/cpu_posix.c',
'src/core/support/cpu_windows.c',
'src/core/support/env_linux.c',
'src/core/support/env_posix.c',
'src/core/support/env_win32.c',
'src/core/support/file.c',
'src/core/support/file_posix.c',
'src/core/support/file_win32.c',
'src/core/support/histogram.c',
'src/core/support/host_port.c',
'src/core/support/log.c',
'src/core/support/log_android.c',
'src/core/support/log_linux.c',
'src/core/support/log_posix.c',
'src/core/support/log_win32.c',
'src/core/support/murmur_hash.c',
'src/core/support/slice.c',
'src/core/support/slice_buffer.c',
'src/core/support/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.c',
'src/core/support/sync.c',
'src/core/support/sync_posix.c',
'src/core/support/sync_win32.c',
'src/core/support/thd.c',
'src/core/support/thd_posix.c',
'src/core/support/thd_win32.c',
'src/core/support/time.c',
'src/core/support/time_posix.c',
'src/core/support/time_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
'src/core/httpcli/httpcli_security_connector.c',
'src/core/security/base64.c',
'src/core/security/client_auth_filter.c',
'src/core/security/credentials.c',
'src/core/security/credentials_metadata.c',
'src/core/security/credentials_posix.c',
'src/core/security/credentials_win32.c',
'src/core/security/google_default_credentials.c',
'src/core/security/handshake.c',
'src/core/security/json_token.c',
'src/core/security/jwt_verifier.c',
'src/core/security/secure_endpoint.c',
'src/core/security/security_connector.c',
'src/core/security/security_context.c',
'src/core/security/server_auth_filter.c',
'src/core/security/server_secure_chttp2.c',
'src/core/surface/init_secure.c',
'src/core/surface/secure_channel_create.c',
'src/core/tsi/fake_transport_security.c',
'src/core/tsi/ssl_transport_security.c',
'src/core/tsi/transport_security.c',
'src/core/census/grpc_context.c',
'src/core/census/grpc_filter.c',
'src/core/channel/channel_args.c',
'src/core/channel/channel_stack.c',
'src/core/channel/client_channel.c',
'src/core/channel/client_uchannel.c',
'src/core/channel/compress_filter.c',
'src/core/channel/connected_channel.c',
'src/core/channel/http_client_filter.c',
'src/core/channel/http_server_filter.c',
'src/core/channel/subchannel_call_holder.c',
'src/core/client_config/client_config.c',
'src/core/client_config/connector.c',
'src/core/client_config/default_initial_connect_string.c',
'src/core/client_config/initial_connect_string.c',
'src/core/client_config/lb_policies/pick_first.c',
'src/core/client_config/lb_policies/round_robin.c',
'src/core/client_config/lb_policy.c',
'src/core/client_config/lb_policy_factory.c',
'src/core/client_config/lb_policy_registry.c',
'src/core/client_config/resolver.c',
'src/core/client_config/resolver_factory.c',
'src/core/client_config/resolver_registry.c',
'src/core/client_config/resolvers/dns_resolver.c',
'src/core/client_config/resolvers/sockaddr_resolver.c',
'src/core/client_config/subchannel.c',
'src/core/client_config/subchannel_factory.c',
'src/core/client_config/uri_parser.c',
'src/core/compression/algorithm.c',
'src/core/compression/message_compress.c',
'src/core/debug/trace.c',
'src/core/httpcli/format_request.c',
'src/core/httpcli/httpcli.c',
'src/core/httpcli/parser.c',
'src/core/iomgr/closure.c',
'src/core/iomgr/endpoint.c',
'src/core/iomgr/endpoint_pair_posix.c',
'src/core/iomgr/endpoint_pair_windows.c',
'src/core/iomgr/exec_ctx.c',
'src/core/iomgr/executor.c',
'src/core/iomgr/fd_posix.c',
'src/core/iomgr/iocp_windows.c',
'src/core/iomgr/iomgr.c',
'src/core/iomgr/iomgr_posix.c',
'src/core/iomgr/iomgr_windows.c',
'src/core/iomgr/pollset_multipoller_with_epoll.c',
'src/core/iomgr/pollset_multipoller_with_poll_posix.c',
'src/core/iomgr/pollset_posix.c',
'src/core/iomgr/pollset_set_posix.c',
'src/core/iomgr/pollset_set_windows.c',
'src/core/iomgr/pollset_windows.c',
'src/core/iomgr/resolve_address_posix.c',
'src/core/iomgr/resolve_address_windows.c',
'src/core/iomgr/sockaddr_utils.c',
'src/core/iomgr/socket_utils_common_posix.c',
'src/core/iomgr/socket_utils_linux.c',
'src/core/iomgr/socket_utils_posix.c',
'src/core/iomgr/socket_windows.c',
'src/core/iomgr/tcp_client_posix.c',
'src/core/iomgr/tcp_client_windows.c',
'src/core/iomgr/tcp_posix.c',
'src/core/iomgr/tcp_server_posix.c',
'src/core/iomgr/tcp_server_windows.c',
'src/core/iomgr/tcp_windows.c',
'src/core/iomgr/time_averaged_stats.c',
'src/core/iomgr/timer.c',
'src/core/iomgr/timer_heap.c',
'src/core/iomgr/udp_server.c',
'src/core/iomgr/wakeup_fd_eventfd.c',
'src/core/iomgr/wakeup_fd_nospecial.c',
'src/core/iomgr/wakeup_fd_pipe.c',
'src/core/iomgr/wakeup_fd_posix.c',
'src/core/iomgr/workqueue_posix.c',
'src/core/iomgr/workqueue_windows.c',
'src/core/json/json.c',
'src/core/json/json_reader.c',
'src/core/json/json_string.c',
'src/core/json/json_writer.c',
'src/core/surface/api_trace.c',
'src/core/surface/byte_buffer.c',
'src/core/surface/byte_buffer_reader.c',
'src/core/surface/call.c',
'src/core/surface/call_details.c',
'src/core/surface/call_log_batch.c',
'src/core/surface/channel.c',
'src/core/surface/channel_connectivity.c',
'src/core/surface/channel_create.c',
'src/core/surface/channel_ping.c',
'src/core/surface/completion_queue.c',
'src/core/surface/event_string.c',
'src/core/surface/init.c',
'src/core/surface/lame_client.c',
'src/core/surface/metadata_array.c',
'src/core/surface/server.c',
'src/core/surface/server_chttp2.c',
'src/core/surface/server_create.c',
'src/core/surface/version.c',
'src/core/transport/byte_stream.c',
'src/core/transport/chttp2/alpn.c',
'src/core/transport/chttp2/bin_encoder.c',
'src/core/transport/chttp2/frame_data.c',
'src/core/transport/chttp2/frame_goaway.c',
'src/core/transport/chttp2/frame_ping.c',
'src/core/transport/chttp2/frame_rst_stream.c',
'src/core/transport/chttp2/frame_settings.c',
'src/core/transport/chttp2/frame_window_update.c',
'src/core/transport/chttp2/hpack_encoder.c',
'src/core/transport/chttp2/hpack_parser.c',
'src/core/transport/chttp2/hpack_table.c',
'src/core/transport/chttp2/huffsyms.c',
'src/core/transport/chttp2/incoming_metadata.c',
'src/core/transport/chttp2/parsing.c',
'src/core/transport/chttp2/status_conversion.c',
'src/core/transport/chttp2/stream_lists.c',
'src/core/transport/chttp2/stream_map.c',
'src/core/transport/chttp2/timeout_encoding.c',
'src/core/transport/chttp2/varint.c',
'src/core/transport/chttp2/writing.c',
'src/core/transport/chttp2_transport.c',
'src/core/transport/connectivity_state.c',
'src/core/transport/metadata.c',
'src/core/transport/metadata_batch.c',
'src/core/transport/static_metadata.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/tracing.c',
]

@ -29,7 +29,7 @@
import threading import threading
from grpc._cython._cygrpc import completion_queue from grpc._cython import cygrpc
class CompletionQueuePollFuture: class CompletionQueuePollFuture:

@ -1,19 +0,0 @@
# Tox (http://tox.testrun.org/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
[tox]
skipsdist = true
envlist = py27
[testenv]
commands =
{envpython} setup.py build_py
{envpython} setup.py test
coverage combine
coverage html --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py'
coverage report --include='grpc/*' --omit='grpc/framework/alpha/*','grpc/early_adopter/*','grpc/framework/base/*','grpc/framework/face/*','grpc/_adapter/fore.py','grpc/_adapter/rear.py'
deps =
-rrequirements.txt
passenv = *

@ -0,0 +1,13 @@
%YAML 1.2
--- |
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_core_dependencies.py.template`!!!
CORE_SOURCE_FILES = [
% for lib in libs:
% if lib.name in python_dependencies.transitive_deps:
% for src in lib.src:
'${src}',
% endfor
% endif
% endfor
]

@ -58,6 +58,10 @@ def mako_plugin(dictionary):
node_modules = dictionary.get('node_modules') node_modules = dictionary.get('node_modules')
targets = dictionary.get('targets') targets = dictionary.get('targets')
for target_list in (libs, node_modules, targets): for target_list in (libs, targets, node_modules):
for target in target_list: for target in target_list:
target['transitive_deps'] = transitive_deps(target, libs) target['transitive_deps'] = transitive_deps(target, libs)
python_dependencies = dictionary.get('python_dependencies')
python_dependencies['transitive_deps'] = (
transitive_deps(python_dependencies, libs))

@ -59,7 +59,7 @@ args = parser.parse_args()
# Move to the root directory of Python GRPC. # Move to the root directory of Python GRPC.
pkgdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), pkgdir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'../../../src/python/grpcio') '../../../')
# Remove previous distributions; they somehow confuse twine. # Remove previous distributions; they somehow confuse twine.
try: try:
shutil.rmtree(os.path.join(pkgdir, 'dist/')) shutil.rmtree(os.path.join(pkgdir, 'dist/'))

@ -48,6 +48,7 @@ RUN apt-get update && apt-get install -y \
libc6-dbg \ libc6-dbg \
libc6-dev \ libc6-dev \
libgtest-dev \ libgtest-dev \
libssl-dev \
libtool \ libtool \
make \ make \
strace \ strace \

@ -43,5 +43,5 @@ make install-certs
make make
# build Python interop client and server # build Python interop client and server
CONFIG=opt ./tools/run_tests/build_python.sh 2.7 CONFIG=opt ./tools/run_tests/build_python.sh

@ -34,16 +34,14 @@ set -ex
cd $(dirname $0)/../.. cd $(dirname $0)/../..
ROOT=`pwd` ROOT=`pwd`
GRPCIO=$ROOT/src/python/grpcio
export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG
export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG
export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
export CFLAGS="-I$ROOT/include -std=c89" export CFLAGS="-I$ROOT/include -std=c89"
export LDFLAGS="-L$ROOT/libs/$CONFIG" export LDFLAGS="-L$ROOT/libs/$CONFIG -L$ROOT/libs/$CONFIG/openssl"
export GRPC_PYTHON_BUILD_WITH_CYTHON=1 export GRPC_PYTHON_BUILD_WITH_CYTHON=1
export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1 export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1
cd $GRPCIO
tox --notest tox --notest
$GRPCIO/.tox/py27/bin/python $GRPCIO/setup.py build $ROOT/.tox/py27/bin/python $ROOT/setup.py build

@ -298,8 +298,8 @@ class PythonLanguage:
def client_cmd(self, args): def client_cmd(self, args):
return [ return [
'src/python/grpcio/.tox/py27/bin/python', '.tox/py27/bin/python',
'src/python/grpcio/setup.py', 'setup.py',
'run_interop', 'run_interop',
'--client', '--client',
'--args=\'{}\''.format(' '.join(args)) '--args=\'{}\''.format(' '.join(args))
@ -310,8 +310,8 @@ class PythonLanguage:
def server_cmd(self, args): def server_cmd(self, args):
return [ return [
'src/python/grpcio/.tox/py27/bin/python', '.tox/py27/bin/python',
'src/python/grpcio/setup.py', 'setup.py',
'run_interop', 'run_interop',
'--server', '--server',
'--args=\'{}\''.format(' '.join(args) + ' --use_tls=true') '--args=\'{}\''.format(' '.join(args) + ' --use_tls=true')

@ -34,18 +34,16 @@ set -ex
cd $(dirname $0)/../.. cd $(dirname $0)/../..
ROOT=`pwd` ROOT=`pwd`
GRPCIO=$ROOT/src/python/grpcio
export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG
export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG export DYLD_LIBRARY_PATH=$ROOT/libs/$CONFIG
export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH export PATH=$ROOT/bins/$CONFIG:$ROOT/bins/$CONFIG/protobuf:$PATH
export CFLAGS="-I$ROOT/include -std=c89" export CFLAGS="-I$ROOT/include -std=c89"
export LDFLAGS="-L$ROOT/libs/$CONFIG" export LDFLAGS="-L$ROOT/libs/$CONFIG -L$ROOT/libs/$CONFIG/openssl"
export GRPC_PYTHON_BUILD_WITH_CYTHON=1 export GRPC_PYTHON_BUILD_WITH_CYTHON=1
export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1 export GRPC_PYTHON_ENABLE_CYTHON_TRACING=1
cd $GRPCIO
tox tox
mkdir -p $ROOT/reports mkdir -p $ROOT/reports
rm -rf $ROOT/reports/python-coverage rm -rf $ROOT/reports/python-coverage
(mv -T $GRPCIO/htmlcov $ROOT/reports/python-coverage) || true (mv -T $ROOT/htmlcov $ROOT/reports/python-coverage) || true

@ -0,0 +1,17 @@
[tox]
skipsdist = true
envlist = py27
[testenv]
setenv =
PYGRPC_ROOT = {toxinidir}/src/python/grpcio/
commands =
{envpython} setup.py build_py
{envpython} setup.py test
{envbindir}/coverage combine
# TODO(atash): we currently ignore cygrpc.pyx due to an insufficiency in Cython's coverage plug-in. Discussion is ongoing.
{envbindir}/coverage html --include='{env:PYGRPC_ROOT}/grpc/*' --omit='{env:PYGRPC_ROOT}/grpc/framework/alpha/*','{env:PYGRPC_ROOT}/grpc/early_adopter/*','{env:PYGRPC_ROOT}/grpc/framework/base/*','{env:PYGRPC_ROOT}/grpc/framework/face/*','{env:PYGRPC_ROOT}/grpc/_adapter/fore.py','{env:PYGRPC_ROOT}/grpc/_adapter/rear.py','{env:PYGRPC_ROOT}/grpc/_cython/cygrpc.pyx'
{envbindir}/coverage report --include='{env:PYGRPC_ROOT}/grpc/*' --omit='{env:PYGRPC_ROOT}/grpc/framework/alpha/*','{env:PYGRPC_ROOT}/grpc/early_adopter/*','{env:PYGRPC_ROOT}/grpc/framework/base/*','{env:PYGRPC_ROOT}/grpc/framework/face/*','{env:PYGRPC_ROOT}/grpc/_adapter/fore.py','{env:PYGRPC_ROOT}/grpc/_adapter/rear.py','{env:PYGRPC_ROOT}/grpc/_cython/cygrpc.pyx'
deps =
-rrequirements.txt
passenv = *
Loading…
Cancel
Save