Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • viteks/nsi-lectures
1 result
Show changes
Commits on Source (2)
Showing
with 197 additions and 37 deletions
%% Cell type:markdown id: tags:
# NSI - 2. přednáška
## [Funkce](#funkce)
* Funkce je obecně pojmenovaný blok kódu
* Funkce je možné opakovaně volat a parametrizovat
* Podobně jako u větvení a cyklů jsou v Pythonu bloky řešeny konzistentním odsazováním
%% Cell type:code id: tags:
``` python
def square(x):
return x*x
a = square(10)
print(a)
```
%% Output
100
%% Cell type:markdown id: tags:
### Argumenty funkcí
* Argumenty funkce jsou vyhodnocovány buď pozičně (tj. stejně, jako v C), nebo je možné je při volání explicitně pojmenovat.
%% Cell type:code id: tags:
``` python
def rectangle(x, y):
print("sirka {}, vyska {}".format(x, y))
rectangle(10, 20)
rectangle(y = 33, x = 20)
```
%% Output
sirka = 10, vyska = 20
sirka = 20, vyska = 33
%% Cell type:markdown id: tags:
### Implicitní hodnota argumentu funkce
* Argumenty funkcí mohou mít defaultní/implicitní hodnotu, která je použita v případě, že argument není při volání funkce uveden.
%% Cell type:code id: tags:
``` python
def cube(x, y, z = 10):
print("zakladna {}x{}, vyska {}".format(x, y, z))
cube(5, 5)
```
%% Output
zakladna 5x5, vyska 10
%% Cell type:markdown id: tags:
### Proměnná jako alias funkce
* V Pythonu je možné přiřadit proměnné funkci a tuto proměnnou pak využít k volání původní funkce (vytvoří se alias)
* Obdoba ukazatele na funkci v C
%% Cell type:code id: tags:
``` python
def plus_one(number):
return number + 1
add_one = plus_one
a = add_one(5)
print(a)
```
%% Output
6
%% Cell type:markdown id: tags:
### Definice funkcí uvnitř jiných funkcí
* Na rozdíl od jiných programovacích jazyků (jako je třeba C) umožňuje Python definovat funkci uvnitř jiné funkce
%% Cell type:code id: tags:
``` python
def plus_one(number):
def add_one(number):
return number + 1
result = add_one(number)
return result
a = plus_one(4)
print(a)
```
%% Output
5
%% Cell type:markdown id: tags:
### Funkce jako argument jiné funkce
%% Cell type:code id: tags:
``` python
def plus_one(number):
return number + 1
def function_call(function):
number_to_add = 5
return function(number_to_add)
a = function_call(plus_one)
print(a)
```
%% Output
6
%% Cell type:markdown id: tags:
### Funkce jako návratová hodnota
%% Cell type:code id: tags:
``` python
def hello_function():
def say_hi():
return "Hi"
return say_hi
hello = hello_function()
hello()
```
%% Output
'Hi'
%% Cell type:markdown id: tags:
## [Dekorátory](#dekorátory)
Dekorátor je návrhový vzor v jazyce Python, který umožňuje uživateli přidat novou funkci k existujícímu objektu, aniž by měnil jeho strukturu. Dekorátory se obvykle používají u funkcí a hrají klíčovou roli při vylepšování nebo úpravě chování funkcí. Tradičně se dekorátory umisťují před definici funkce, kterou chcete ozdobit.
* Dekorátor je funkce, která dostane jeden argument a vrátí jednu hodnotu.
* Specialita dekorátoru je v tom, že jak argument, tak návratová hodnota jsou zase jiné funkce.
* Dekorátorům se také říká funkce vyšších řádů
%% Cell type:code id: tags:
``` python
def uppercase_decorator(function):
def wrapper():
func = function()
make_uppercase = func.upper()
return make_uppercase
return wrapper
```
%% Cell type:markdown id: tags:
Naše funkce dekorátoru přijímá jako argument funkci, a proto budeme definovat funkci a předávat ji našemu dekorátoru. Již dříve jsme se dozvěděli, že funkci můžeme přiřadit proměnné. Tento trik použijeme k volání naší funkce dekorátoru.
%% Cell type:code id: tags:
``` python
def say_hi():
return 'hello there'
decorate = uppercase_decorator(say_hi)
decorate()
```
%% Output
'HELLO THERE'
%% Cell type:markdown id: tags:
Python nám však poskytuje mnohem jednodušší způsob použití dekorátorů. Jednoduše použijeme symbol @ před funkcí, kterou chceme ozdobit. Ukažme si to níže v praxi.
%% Cell type:code id: tags:
``` python
@uppercase_decorator
def say_hi():
return 'hello there'
say_hi()
```
%% Output
'HELLO THERE'
%% Cell type:markdown id: tags:
### Dekorátory s argumenty
%% Cell type:code id: tags:
``` python
def decorator_with_arguments(function):
def wrapper_accepting_arguments(arg1, arg2):
print("My arguments are: {0}, {1}".format(arg1,arg2))
function(arg1, arg2)
return wrapper_accepting_arguments
@decorator_with_arguments
def cities(city_one, city_two):
print("Cities I love are {0} and {1}".format(city_one, city_two))
cities("Nairobi", "Accra")
```
%% Output
My arguments are: Nairobi, Accra
Cities I love are Nairobi and Accra
%% Cell type:markdown id: tags:
## Předávání parametrů funkcím
* parametr drží odkaz na předanou proměnnou
* změna parametru změní i předanou proměnnou
* pro neměnitelné typy tedy v podstatě funguje jako předávání hodnotou
* čísla, řetězce, n-tice (tuples)
* pro měnitelné typy jako předávání odkazem
* pozor: přířazení znamená změnu odkazu
Připomenutí
* neměnitelné typy: int, str, tuple, ...
* měnitelné typy: list, dict, ...
%% Cell type:markdown id: tags:
### Neměnný datový typ jako argument funkce
%% Cell type:code id: tags:
``` python
def update_param_int(x):
x = x + 1
a = 1
print("hodnota a pred volanim: {}".format(a))
update_param_int(a)
print("hodnota a po volani: {}".format(a))
```
%% Output
hodnota a pred volanim: 1
hodnota a po volani: 1
%% Cell type:markdown id: tags:
### Měnitelný datový typ jako parametr funkce
%% Cell type:code id: tags:
``` python
def update_param_list(x):
x.append(3)
a = [1, 2]
print("hodnota a pred volanim: {}".format(a))
update_param_list(a)
print("hodnota a po volani: {}".format(a))
```
%% Output
hodnota a pred volanim: [1, 2]
hodnota a po volani: [1, 2, 3]
%% Cell type:code id: tags:
``` python
def change_param_list(x):
x = [1, 2, 3]
a = [1, 2]
print("hodnota a pred volanim: {}".format(a))
change_param_list(a)
print("hodnota a po volani: {}".format(a))
```
%% Output
hodnota a pred volanim: [1, 2]
hodnota a po volani: [1, 2]
%% Cell type:markdown id: tags:
## [Třídy a objekty](#tridy-objekty)
* Třída představuje definici datového typu a objekt hodnotu
* Každý objekt má své atributy a metody
* atributy jsou vlastnostmi objektu a/nebo data - vnitřní stav
* metody umožňují manipulaci s atributy a představují schopnosti objektu komunikovat s vnějším světem - definují rozhraní
### Třída
* Třída by měla obsahovat konstruktor - metodu, která inicializuje instancionovaný objekt
* Metodám jsou implicitně předávány reference na objekt jako první argument metod
%% Cell type:code id: tags:
``` python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print("My name is ", self.name)
print("I am ", self.age, "years old")
```
%% Cell type:markdown id: tags:
### Objekt
%% Cell type:code id: tags:
``` python
homer = Person("Homer Simpson")
bart = Person("Bart Simpson")
homer.introduce()
bart.introduce()
```
%% Cell type:markdown id: tags:
### Privátní a veřejné atributy a metody
Privátní metody a atributy mohou využívat jen ty třídy, které je definují. V příkladu je demonstrován i způsob, jak je možné na základě existující třídy vytvořit třídu novou, která dědí vlastnosti rodičovské (bázové) třídy.
#### Vytvoření bázové třídy
%% Cell type:code id: tags:
``` python
class Base:
# veřejná metoda (v Pydhonu implicitně všechny)
def fun(self):
print("Veřejná metoda")
# privátní metoda
def __fun(self):
print("Privátní metoda")
```
%% Cell type:markdown id: tags:
#### Vytvoření derivované třídy
%% Cell type:code id: tags:
``` python
class Derived(Base):
def __init__(self):
# volání konstruktoru bázové třídy
Base.__init__(self)
def call_public(self):
# volání veřejné metody bázové třídy
print("Uvnitř derivované třídy")
self.fun()
def call_private(self):
# volání privátní metody bázové třídy
self.__fun()
```
%% Cell type:code id: tags:
``` python
obj1 = Base()
# volání veřejných metod
obj1.fun()
obj2 = Derived()
obj2.call_public()
# odkomentování obj1.__fun() will
# vyvolá vyjímku AttributeError
# obj1.__fun()
# odkomentování obj2.call_private()
# také vyvolá vyjímku AttributeError
# obj2.call_private()
```
%% Output
Veřejná metoda
Uvnitř derivované třídy
Veřejná metoda
%% Cell type:markdown id: tags:
#### Ošetření vyjímky
#### Ošetření výjimky
%% Cell type:code id: tags:
``` python
try:
obj1.__fun()
except AttributeError:
print('Vyjímka ošetřena')
print('Výjimka ošetřena')
```
%% Output
Vyjímka ošetřena
Výjimka ošetřena
%% Cell type:markdown id: tags:
#### Name mangling
Python umožňuje přístup k privátním atributům a metodám prostřednictvím metody, která se jmenuje *data mangling*.
%% Cell type:code id: tags:
``` python
obj1._Base__fun()
```
%% Output
Privátní metoda
......
<?xml version="1.0" encoding="UTF-8" ?>
<book>
<title>Python Basics</title>
<page_count>635</page_count>
<pub_date>2021-03-16</pub_date>
<authors>
<author>
<name>David Amos</name>
</author>
<author name="Joanna" test="1">
<name>Joanna Jablonski</name>
</author>
<author name="Dan" test="2">
<name>Dan Bader</name>
</author>
<author name="Fletcher" test="3">
<name>Fletcher Heisler</name>
</author>
</authors>
<isbn13>978-1775093329</isbn13>
<genre>Education</genre>
</book>
\ No newline at end of file
lec03/figs/Comparison-of-Majore-IOT-Protocols.png

64.1 KiB

lec03/figs/api.png

254 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="156px" preserveAspectRatio="none" style="width:251px;height:156px;" version="1.1" viewBox="0 0 251 156" width="251px" zoomAndPan="magnify"><defs><filter height="300%" id="f10nhrhzv5m7vy" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#f10nhrhzv5m7vy)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="200" y="69.4297"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="42" x2="42" y1="38.2969" y2="116.5625"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="205" x2="205" y1="38.2969" y2="116.5625"/><rect fill="#FEFECE" filter="url(#f10nhrhzv5m7vy)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="64" x="8" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="50" x="15" y="22.9951">Sender</text><rect fill="#FEFECE" filter="url(#f10nhrhzv5m7vy)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="64" x="8" y="115.5625"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="50" x="15" y="135.5576">Sender</text><rect fill="#FEFECE" filter="url(#f10nhrhzv5m7vy)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="74" x="166" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="60" x="173" y="22.9951">Receiver</text><rect fill="#FEFECE" filter="url(#f10nhrhzv5m7vy)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="74" x="166" y="115.5625"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="60" x="173" y="135.5576">Receiver</text><rect fill="#FFFFFF" filter="url(#f10nhrhzv5m7vy)" height="29.1328" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="200" y="69.4297"/><polygon fill="#A80036" points="188,65.4297,198,69.4297,188,73.4297,192,69.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="42" x2="194" y1="69.4297" y2="69.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="137" x="49" y="64.3638">CON (Msg ID = 1337)</text><polygon fill="#A80036" points="53,94.5625,43,98.5625,53,102.5625,49,98.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="47" x2="204" y1="98.5625" y2="98.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="134" x="59" y="93.4966">ACK (Msg ID = 1337)</text><!--MD5=[d2a5b4bb217bb68c28955b0c12c0a588]
@startuml
Sender -> Receiver: CON (Msg ID = 1337)
activate Receiver
Receiver -> Sender: ACK (Msg ID = 1337)
deactivate Receiver
@enduml
PlantUML version 1.2019.12(Sun Nov 03 10:24:54 UTC 2019)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 1.8.0_232-heroku-b09
Operating System: Linux
Default Encoding: UTF-8
Language: en
Country: US
--></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="127px" preserveAspectRatio="none" style="width:250px;height:127px;" version="1.1" viewBox="0 0 250 127" width="250px" zoomAndPan="magnify"><defs><filter height="300%" id="fwmwtwolk5wst" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="42" x2="42" y1="38.2969" y2="87.4297"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="204" x2="204" y1="38.2969" y2="87.4297"/><rect fill="#FEFECE" filter="url(#fwmwtwolk5wst)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="64" x="8" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="50" x="15" y="22.9951">Sender</text><rect fill="#FEFECE" filter="url(#fwmwtwolk5wst)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="64" x="8" y="86.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="50" x="15" y="106.4248">Sender</text><rect fill="#FEFECE" filter="url(#fwmwtwolk5wst)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="74" x="165" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="60" x="172" y="22.9951">Receiver</text><rect fill="#FEFECE" filter="url(#fwmwtwolk5wst)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="74" x="165" y="86.4297"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="60" x="172" y="106.4248">Receiver</text><polygon fill="#A80036" points="192,65.4297,202,69.4297,192,73.4297,196,69.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="42" x2="198" y1="69.4297" y2="69.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="138" x="49" y="64.3638">NON (Msg ID = 1337)</text><!--MD5=[3a409d7e052f65619f6b6b76247fdaa8]
@startuml
Sender -> Receiver: NON (Msg ID = 1337)
@enduml
PlantUML version 1.2019.12(Sun Nov 03 10:24:54 UTC 2019)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Java Version: 1.8.0_232-heroku-b09
Operating System: Linux
Default Encoding: UTF-8
Language: en
Country: US
--></g></svg>
\ No newline at end of file
lec03/figs/coap-fig3.png

4.49 KiB

lec03/figs/coap-fig4.png

232 KiB

lec03/figs/iot-04.png

69.3 KiB

lec03/figs/iot-06.png

11.5 KiB

lec03/figs/iot-07.png

62.7 KiB

lec03/figs/iot-14.png

359 KiB

lec03/figs/iot-stack.jpg

93.7 KiB

File added
File added
from flask import Flask, jsonify
import grpc
import books_pb2
import books_pb2_grpc
app = Flask(__name__)
@app.route('/api/books', methods=['GET'])
def get_books():
try:
# Make gRPC call to the BookService
with grpc.insecure_channel('localhost:50051') as channel:
stub = books_pb2_grpc.BookServiceStub(channel)
grpc_request = books_pb2.GetBooksRequest()
grpc_response = stub.GetBooks(grpc_request)
# Process gRPC response and return to the Flask app
books_data = [{'id': book.id, 'title': book.title, 'author': book.author} for book in grpc_response.books]
return jsonify({'books': books_data})
except Exception as e:
return jsonify({'message': f"Error: {e}"})
if __name__ == '__main__':
app.run(debug=True)
\ No newline at end of file
import grpc
from concurrent import futures
import books_pb2
import books_pb2_grpc
class BookService(books_pb2_grpc.BookServiceServicer):
def GetBooks(self, request, context):
# Simulate fetching books from a database or external service
books = [
books_pb2.Book(id="1", title="Book 1", author="Author 1"),
books_pb2.Book(id="2", title="Book 2", author="Author 2"),
# Add more books as needed
]
return books_pb2.GetBooksResponse(books=books)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
books_pb2_grpc.add_BookServiceServicer_to_server(BookService(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("gRPC Server started. Listening on port 50051...")
try:
while True:
pass
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
\ No newline at end of file
syntax = "proto3";
package bookstore;
service BookService {
rpc GetBooks (GetBooksRequest) returns (GetBooksResponse);
}
message GetBooksRequest {
}
message GetBooksResponse {
repeated Book books = 1;
}
message Book {
string id = 1;
string title = 2;
string author = 3;
}
\ No newline at end of file
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: books.proto
# Protobuf Python Version: 4.25.1
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x62ooks.proto\x12\tbookstore\"\x11\n\x0fGetBooksRequest\"2\n\x10GetBooksResponse\x12\x1e\n\x05\x62ooks\x18\x01 \x03(\x0b\x32\x0f.bookstore.Book\"1\n\x04\x42ook\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x0e\n\x06\x61uthor\x18\x03 \x01(\t2R\n\x0b\x42ookService\x12\x43\n\x08GetBooks\x12\x1a.bookstore.GetBooksRequest\x1a\x1b.bookstore.GetBooksResponseb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'books_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_globals['_GETBOOKSREQUEST']._serialized_start=26
_globals['_GETBOOKSREQUEST']._serialized_end=43
_globals['_GETBOOKSRESPONSE']._serialized_start=45
_globals['_GETBOOKSRESPONSE']._serialized_end=95
_globals['_BOOK']._serialized_start=97
_globals['_BOOK']._serialized_end=146
_globals['_BOOKSERVICE']._serialized_start=148
_globals['_BOOKSERVICE']._serialized_end=230
# @@protoc_insertion_point(module_scope)
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import books_pb2 as books__pb2
class BookServiceStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetBooks = channel.unary_unary(
'/bookstore.BookService/GetBooks',
request_serializer=books__pb2.GetBooksRequest.SerializeToString,
response_deserializer=books__pb2.GetBooksResponse.FromString,
)
class BookServiceServicer(object):
"""Missing associated documentation comment in .proto file."""
def GetBooks(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_BookServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetBooks': grpc.unary_unary_rpc_method_handler(
servicer.GetBooks,
request_deserializer=books__pb2.GetBooksRequest.FromString,
response_serializer=books__pb2.GetBooksResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'bookstore.BookService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class BookService(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def GetBooks(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/bookstore.BookService/GetBooks',
books__pb2.GetBooksRequest.SerializeToString,
books__pb2.GetBooksResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)