├── server ├── generate-code.md ├── Pipfile ├── server.py ├── service_pb2_grpc.py ├── .gitignore ├── service_pb2.py └── Pipfile.lock ├── readme.md ├── service_definitions └── service.proto └── client ├── Client.csproj ├── Program.cs ├── .gitignore └── Data.cs /server/generate-code.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | python -m grpc_tools.protoc -I..\service_definitions\ --python_out=. --grpc_python_out=. ..\service_definitions\service.proto 3 | ``` -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | gr-pizzeria 2 | =========== 3 | 4 | ## Client 5 | 6 | ### Install instructions 7 | 8 | ``` 9 | dotnet add package Grpc.Tools 10 | ``` 11 | 12 | ```shell 13 | protoc --csharp_out=client/ .\service_definitions\service.proto 14 | ``` 15 | -------------------------------------------------------------------------------- /server/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | grpcio-tools = "*" 10 | googleapis-common-protos = "*" 11 | grpcio = "*" 12 | 13 | [requires] 14 | python_version = "3.8" 15 | -------------------------------------------------------------------------------- /service_definitions/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Pizza { 4 | repeated string toppings = 1; 5 | int32 inches = 2; 6 | bool cheese = 3; 7 | } 8 | 9 | message Order { 10 | repeated Pizza pizzas = 1; 11 | string customer_name = 2; 12 | string address = 3; 13 | } 14 | 15 | message OrderConfirmation { 16 | int64 estimated_delivery = 1; 17 | } 18 | 19 | message Empty { 20 | } 21 | 22 | service Pizzeria { 23 | rpc IsReady(Empty) returns (Empty) {} 24 | rpc RegisterOrder(Order) returns (OrderConfirmation) {} 25 | } -------------------------------------------------------------------------------- /client/Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | all 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /server/server.py: -------------------------------------------------------------------------------- 1 | from concurrent import futures 2 | from datetime import datetime, timedelta 3 | 4 | import grpc 5 | 6 | from service_pb2 import OrderConfirmation 7 | from service_pb2_grpc import PizzeriaServicer, add_PizzeriaServicer_to_server 8 | 9 | 10 | class PizzeriaService(PizzeriaServicer): 11 | 12 | def IsReady(self, request, context): 13 | return request 14 | 15 | def RegisterOrder(self, request, context): 16 | print("New order received:") 17 | print(f"\tFrom: {request.customer_name}") 18 | print(f"\tTo: {request.address}") 19 | print("\tPizzas:") 20 | for idx, pizza in enumerate(request.pizzas, 1): 21 | toppings = ", ".join(pizza.toppings) 22 | print(f"\t\tPizza {idx}: {pizza.inches}\" ({toppings})") 23 | 24 | estimated_delivery = (datetime.now() + timedelta(minutes=30)) - datetime(1970, 1, 1) 25 | return OrderConfirmation(estimated_delivery=int(estimated_delivery.total_seconds())) 26 | 27 | 28 | def serve(): 29 | server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) 30 | add_PizzeriaServicer_to_server(PizzeriaService(), server) 31 | server.add_insecure_port('[::]:50051') 32 | print("The server is running!") 33 | server.start() 34 | server.wait_for_termination() 35 | 36 | 37 | if __name__ == "__main__": 38 | serve() 39 | -------------------------------------------------------------------------------- /client/Program.cs: -------------------------------------------------------------------------------- 1 | using Grpc.Core; 2 | using Grpc.Net.Client; 3 | using Polly; 4 | using System; 5 | using System.IO; 6 | using System.Threading; 7 | 8 | namespace Client 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | 15 | var random = new Random(); 16 | 17 | var client = Policy 18 | .Handle() 19 | .WaitAndRetry( 20 | 5, 21 | retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), 22 | (exception, timeSpan, context) => 23 | { 24 | Console.WriteLine($"Server not available yet!"); 25 | } 26 | ).Execute(() => GetClient("http://127.0.0.1:50051")); 27 | 28 | while (true) 29 | { 30 | var customer = Customer.Customers[random.Next(Customer.Customers.Length)]; 31 | var order = new Order 32 | { 33 | Address = customer.Address, 34 | CustomerName = customer.CustomerName, 35 | }; 36 | 37 | 38 | var numberOfPizzas = random.Next(1, 5); 39 | for (int idx = 0; idx < numberOfPizzas; idx++) 40 | { 41 | var pizza = new Pizza 42 | { 43 | Cheese = random.Next(10) % 2 == 0, 44 | Inches = random.Next(10, 21) 45 | }; 46 | 47 | foreach (string topping in Toppings.Select(10)) 48 | { 49 | pizza.Toppings.Add(topping); 50 | } 51 | order.Pizzas.Add(pizza); 52 | } 53 | 54 | var confirmation = client.RegisterOrder(order); 55 | Console.WriteLine($"Your order will arrive at: {ToDateString(confirmation.EstimatedDelivery)}"); 56 | Thread.Sleep(1000 * random.Next(1, 4)); 57 | } 58 | } 59 | 60 | static Pizzeria.PizzeriaClient GetClient(string address) 61 | { 62 | // This switch must be set before creating the GrpcChannel/HttpClient. 63 | AppContext.SetSwitch( 64 | "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); 65 | 66 | var channel = GrpcChannel.ForAddress(address); 67 | var client = new Pizzeria.PizzeriaClient(channel); 68 | client.IsReady(new Empty()); 69 | return client; 70 | } 71 | 72 | static string ToDateString(long date) 73 | { 74 | var dt = DateTime.MinValue.AddSeconds(date); 75 | return dt.ToShortDateString() + " " + dt.ToShortTimeString(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /server/service_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import service_pb2 as service__pb2 6 | 7 | 8 | class PizzeriaStub(object): 9 | """Missing associated documentation comment in .proto file.""" 10 | 11 | def __init__(self, channel): 12 | """Constructor. 13 | 14 | Args: 15 | channel: A grpc.Channel. 16 | """ 17 | self.IsReady = channel.unary_unary( 18 | '/Pizzeria/IsReady', 19 | request_serializer=service__pb2.Empty.SerializeToString, 20 | response_deserializer=service__pb2.Empty.FromString, 21 | ) 22 | self.RegisterOrder = channel.unary_unary( 23 | '/Pizzeria/RegisterOrder', 24 | request_serializer=service__pb2.Order.SerializeToString, 25 | response_deserializer=service__pb2.OrderConfirmation.FromString, 26 | ) 27 | 28 | 29 | class PizzeriaServicer(object): 30 | """Missing associated documentation comment in .proto file.""" 31 | 32 | def IsReady(self, request, context): 33 | """Missing associated documentation comment in .proto file.""" 34 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 35 | context.set_details('Method not implemented!') 36 | raise NotImplementedError('Method not implemented!') 37 | 38 | def RegisterOrder(self, request, context): 39 | """Missing associated documentation comment in .proto file.""" 40 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 41 | context.set_details('Method not implemented!') 42 | raise NotImplementedError('Method not implemented!') 43 | 44 | 45 | def add_PizzeriaServicer_to_server(servicer, server): 46 | rpc_method_handlers = { 47 | 'IsReady': grpc.unary_unary_rpc_method_handler( 48 | servicer.IsReady, 49 | request_deserializer=service__pb2.Empty.FromString, 50 | response_serializer=service__pb2.Empty.SerializeToString, 51 | ), 52 | 'RegisterOrder': grpc.unary_unary_rpc_method_handler( 53 | servicer.RegisterOrder, 54 | request_deserializer=service__pb2.Order.FromString, 55 | response_serializer=service__pb2.OrderConfirmation.SerializeToString, 56 | ), 57 | } 58 | generic_handler = grpc.method_handlers_generic_handler( 59 | 'Pizzeria', rpc_method_handlers) 60 | server.add_generic_rpc_handlers((generic_handler,)) 61 | 62 | 63 | # This class is part of an EXPERIMENTAL API. 64 | class Pizzeria(object): 65 | """Missing associated documentation comment in .proto file.""" 66 | 67 | @staticmethod 68 | def IsReady(request, 69 | target, 70 | options=(), 71 | channel_credentials=None, 72 | call_credentials=None, 73 | insecure=False, 74 | compression=None, 75 | wait_for_ready=None, 76 | timeout=None, 77 | metadata=None): 78 | return grpc.experimental.unary_unary(request, target, '/Pizzeria/IsReady', 79 | service__pb2.Empty.SerializeToString, 80 | service__pb2.Empty.FromString, 81 | options, channel_credentials, 82 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 83 | 84 | @staticmethod 85 | def RegisterOrder(request, 86 | target, 87 | options=(), 88 | channel_credentials=None, 89 | call_credentials=None, 90 | insecure=False, 91 | compression=None, 92 | wait_for_ready=None, 93 | timeout=None, 94 | metadata=None): 95 | return grpc.experimental.unary_unary(request, target, '/Pizzeria/RegisterOrder', 96 | service__pb2.Order.SerializeToString, 97 | service__pb2.OrderConfirmation.FromString, 98 | options, channel_credentials, 99 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 100 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/python,pycharm+all 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm+all 4 | 5 | ### PyCharm+all ### 6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 8 | 9 | # User-specific stuff 10 | .idea/**/workspace.xml 11 | .idea/**/tasks.xml 12 | .idea/**/usage.statistics.xml 13 | .idea/**/dictionaries 14 | .idea/**/shelf 15 | 16 | # Generated files 17 | .idea/**/contentModel.xml 18 | 19 | # Sensitive or high-churn files 20 | .idea/**/dataSources/ 21 | .idea/**/dataSources.ids 22 | .idea/**/dataSources.local.xml 23 | .idea/**/sqlDataSources.xml 24 | .idea/**/dynamic.xml 25 | .idea/**/uiDesigner.xml 26 | .idea/**/dbnavigator.xml 27 | 28 | # Gradle 29 | .idea/**/gradle.xml 30 | .idea/**/libraries 31 | 32 | # Gradle and Maven with auto-import 33 | # When using Gradle or Maven with auto-import, you should exclude module files, 34 | # since they will be recreated, and may cause churn. Uncomment if using 35 | # auto-import. 36 | # .idea/artifacts 37 | # .idea/compiler.xml 38 | # .idea/jarRepositories.xml 39 | # .idea/modules.xml 40 | # .idea/*.iml 41 | # .idea/modules 42 | # *.iml 43 | # *.ipr 44 | 45 | # CMake 46 | cmake-build-*/ 47 | 48 | # Mongo Explorer plugin 49 | .idea/**/mongoSettings.xml 50 | 51 | # File-based project format 52 | *.iws 53 | 54 | # IntelliJ 55 | out/ 56 | 57 | # mpeltonen/sbt-idea plugin 58 | .idea_modules/ 59 | 60 | # JIRA plugin 61 | atlassian-ide-plugin.xml 62 | 63 | # Cursive Clojure plugin 64 | .idea/replstate.xml 65 | 66 | # Crashlytics plugin (for Android Studio and IntelliJ) 67 | com_crashlytics_export_strings.xml 68 | crashlytics.properties 69 | crashlytics-build.properties 70 | fabric.properties 71 | 72 | # Editor-based Rest Client 73 | .idea/httpRequests 74 | 75 | # Android studio 3.1+ serialized cache file 76 | .idea/caches/build_file_checksums.ser 77 | 78 | ### PyCharm+all Patch ### 79 | # Ignores the whole .idea folder and all .iml files 80 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 81 | 82 | .idea/ 83 | 84 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 85 | 86 | *.iml 87 | modules.xml 88 | .idea/misc.xml 89 | *.ipr 90 | 91 | # Sonarlint plugin 92 | .idea/sonarlint 93 | 94 | ### Python ### 95 | # Byte-compiled / optimized / DLL files 96 | __pycache__/ 97 | *.py[cod] 98 | *$py.class 99 | 100 | # C extensions 101 | *.so 102 | 103 | # Distribution / packaging 104 | .Python 105 | build/ 106 | develop-eggs/ 107 | dist/ 108 | downloads/ 109 | eggs/ 110 | .eggs/ 111 | lib/ 112 | lib64/ 113 | parts/ 114 | sdist/ 115 | var/ 116 | wheels/ 117 | pip-wheel-metadata/ 118 | share/python-wheels/ 119 | *.egg-info/ 120 | .installed.cfg 121 | *.egg 122 | MANIFEST 123 | 124 | # PyInstaller 125 | # Usually these files are written by a python script from a template 126 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 127 | *.manifest 128 | *.spec 129 | 130 | # Installer logs 131 | pip-log.txt 132 | pip-delete-this-directory.txt 133 | 134 | # Unit test / coverage reports 135 | htmlcov/ 136 | .tox/ 137 | .nox/ 138 | .coverage 139 | .coverage.* 140 | .cache 141 | nosetests.xml 142 | coverage.xml 143 | *.cover 144 | *.py,cover 145 | .hypothesis/ 146 | .pytest_cache/ 147 | pytestdebug.log 148 | 149 | # Translations 150 | *.mo 151 | *.pot 152 | 153 | # Django stuff: 154 | *.log 155 | local_settings.py 156 | db.sqlite3 157 | db.sqlite3-journal 158 | 159 | # Flask stuff: 160 | instance/ 161 | .webassets-cache 162 | 163 | # Scrapy stuff: 164 | .scrapy 165 | 166 | # Sphinx documentation 167 | docs/_build/ 168 | doc/_build/ 169 | 170 | # PyBuilder 171 | target/ 172 | 173 | # Jupyter Notebook 174 | .ipynb_checkpoints 175 | 176 | # IPython 177 | profile_default/ 178 | ipython_config.py 179 | 180 | # pyenv 181 | .python-version 182 | 183 | # pipenv 184 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 185 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 186 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 187 | # install all needed dependencies. 188 | #Pipfile.lock 189 | 190 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 191 | __pypackages__/ 192 | 193 | # Celery stuff 194 | celerybeat-schedule 195 | celerybeat.pid 196 | 197 | # SageMath parsed files 198 | *.sage.py 199 | 200 | # Environments 201 | .env 202 | .venv 203 | env/ 204 | venv/ 205 | ENV/ 206 | env.bak/ 207 | venv.bak/ 208 | pythonenv* 209 | 210 | # Spyder project settings 211 | .spyderproject 212 | .spyproject 213 | 214 | # Rope project settings 215 | .ropeproject 216 | 217 | # mkdocs documentation 218 | /site 219 | 220 | # mypy 221 | .mypy_cache/ 222 | .dmypy.json 223 | dmypy.json 224 | 225 | # Pyre type checker 226 | .pyre/ 227 | 228 | # pytype static type analyzer 229 | .pytype/ 230 | 231 | # profiling data 232 | .prof 233 | 234 | # End of https://www.toptal.com/developers/gitignore/api/python,pycharm+all -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/dotnetcore,csharp 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=dotnetcore,csharp 4 | 5 | ### Csharp ### 6 | ## Ignore Visual Studio temporary files, build results, and 7 | ## files generated by popular Visual Studio add-ons. 8 | ## 9 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 10 | 11 | # User-specific files 12 | *.rsuser 13 | *.suo 14 | *.user 15 | *.userosscache 16 | *.sln.docstates 17 | 18 | # User-specific files (MonoDevelop/Xamarin Studio) 19 | *.userprefs 20 | 21 | # Mono auto generated files 22 | mono_crash.* 23 | 24 | # Build results 25 | [Dd]ebug/ 26 | [Dd]ebugPublic/ 27 | [Rr]elease/ 28 | [Rr]eleases/ 29 | x64/ 30 | x86/ 31 | [Aa][Rr][Mm]/ 32 | [Aa][Rr][Mm]64/ 33 | bld/ 34 | [Bb]in/ 35 | [Oo]bj/ 36 | [Ll]og/ 37 | [Ll]ogs/ 38 | 39 | # Visual Studio 2015/2017 cache/options directory 40 | .vs/ 41 | # Uncomment if you have tasks that create the project's static files in wwwroot 42 | #wwwroot/ 43 | 44 | # Visual Studio 2017 auto generated files 45 | Generated\ Files/ 46 | 47 | # MSTest test Results 48 | [Tt]est[Rr]esult*/ 49 | [Bb]uild[Ll]og.* 50 | 51 | # NUnit 52 | *.VisualState.xml 53 | TestResult.xml 54 | nunit-*.xml 55 | 56 | # Build Results of an ATL Project 57 | [Dd]ebugPS/ 58 | [Rr]eleasePS/ 59 | dlldata.c 60 | 61 | # Benchmark Results 62 | BenchmarkDotNet.Artifacts/ 63 | 64 | # .NET Core 65 | project.lock.json 66 | project.fragment.lock.json 67 | artifacts/ 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*[.json, .xml, .info] 147 | 148 | # Visual Studio code coverage results 149 | *.coverage 150 | *.coveragexml 151 | 152 | # NCrunch 153 | _NCrunch_* 154 | .*crunch*.local.xml 155 | nCrunchTemp_* 156 | 157 | # MightyMoose 158 | *.mm.* 159 | AutoTest.Net/ 160 | 161 | # Web workbench (sass) 162 | .sass-cache/ 163 | 164 | # Installshield output folder 165 | [Ee]xpress/ 166 | 167 | # DocProject is a documentation generator add-in 168 | DocProject/buildhelp/ 169 | DocProject/Help/*.HxT 170 | DocProject/Help/*.HxC 171 | DocProject/Help/*.hhc 172 | DocProject/Help/*.hhk 173 | DocProject/Help/*.hhp 174 | DocProject/Help/Html2 175 | DocProject/Help/html 176 | 177 | # Click-Once directory 178 | publish/ 179 | 180 | # Publish Web Output 181 | *.[Pp]ublish.xml 182 | *.azurePubxml 183 | # Note: Comment the next line if you want to checkin your web deploy settings, 184 | # but database connection strings (with potential passwords) will be unencrypted 185 | *.pubxml 186 | *.publishproj 187 | 188 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 189 | # checkin your Azure Web App publish settings, but sensitive information contained 190 | # in these scripts will be unencrypted 191 | PublishScripts/ 192 | 193 | # NuGet Packages 194 | *.nupkg 195 | # NuGet Symbol Packages 196 | *.snupkg 197 | # The packages folder can be ignored because of Package Restore 198 | **/[Pp]ackages/* 199 | # except build/, which is used as an MSBuild target. 200 | !**/[Pp]ackages/build/ 201 | # Uncomment if necessary however generally it will be regenerated when needed 202 | #!**/[Pp]ackages/repositories.config 203 | # NuGet v3's project.json files produces more ignorable files 204 | *.nuget.props 205 | *.nuget.targets 206 | 207 | # Microsoft Azure Build Output 208 | csx/ 209 | *.build.csdef 210 | 211 | # Microsoft Azure Emulator 212 | ecf/ 213 | rcf/ 214 | 215 | # Windows Store app package directories and files 216 | AppPackages/ 217 | BundleArtifacts/ 218 | Package.StoreAssociation.xml 219 | _pkginfo.txt 220 | *.appx 221 | *.appxbundle 222 | *.appxupload 223 | 224 | # Visual Studio cache files 225 | # files ending in .cache can be ignored 226 | *.[Cc]ache 227 | # but keep track of directories ending in .cache 228 | !?*.[Cc]ache/ 229 | 230 | # Others 231 | ClientBin/ 232 | ~$* 233 | *~ 234 | *.dbmdl 235 | *.dbproj.schemaview 236 | *.jfm 237 | *.pfx 238 | *.publishsettings 239 | orleans.codegen.cs 240 | 241 | # Including strong name files can present a security risk 242 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 243 | #*.snk 244 | 245 | # Since there are multiple workflows, uncomment next line to ignore bower_components 246 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 247 | #bower_components/ 248 | 249 | # RIA/Silverlight projects 250 | Generated_Code/ 251 | 252 | # Backup & report files from converting an old project file 253 | # to a newer Visual Studio version. Backup files are not needed, 254 | # because we have git ;-) 255 | _UpgradeReport_Files/ 256 | Backup*/ 257 | UpgradeLog*.XML 258 | UpgradeLog*.htm 259 | ServiceFabricBackup/ 260 | *.rptproj.bak 261 | 262 | # SQL Server files 263 | *.mdf 264 | *.ldf 265 | *.ndf 266 | 267 | # Business Intelligence projects 268 | *.rdl.data 269 | *.bim.layout 270 | *.bim_*.settings 271 | *.rptproj.rsuser 272 | *- [Bb]ackup.rdl 273 | *- [Bb]ackup ([0-9]).rdl 274 | *- [Bb]ackup ([0-9][0-9]).rdl 275 | 276 | # Microsoft Fakes 277 | FakesAssemblies/ 278 | 279 | # GhostDoc plugin setting file 280 | *.GhostDoc.xml 281 | 282 | # Node.js Tools for Visual Studio 283 | .ntvs_analysis.dat 284 | node_modules/ 285 | 286 | # Visual Studio 6 build log 287 | *.plg 288 | 289 | # Visual Studio 6 workspace options file 290 | *.opt 291 | 292 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 293 | *.vbw 294 | 295 | # Visual Studio LightSwitch build output 296 | **/*.HTMLClient/GeneratedArtifacts 297 | **/*.DesktopClient/GeneratedArtifacts 298 | **/*.DesktopClient/ModelManifest.xml 299 | **/*.Server/GeneratedArtifacts 300 | **/*.Server/ModelManifest.xml 301 | _Pvt_Extensions 302 | 303 | # Paket dependency manager 304 | .paket/paket.exe 305 | paket-files/ 306 | 307 | # FAKE - F# Make 308 | .fake/ 309 | 310 | # CodeRush personal settings 311 | .cr/personal 312 | 313 | # Python Tools for Visual Studio (PTVS) 314 | __pycache__/ 315 | *.pyc 316 | 317 | # Cake - Uncomment if you are using it 318 | # tools/** 319 | # !tools/packages.config 320 | 321 | # Tabs Studio 322 | *.tss 323 | 324 | # Telerik's JustMock configuration file 325 | *.jmconfig 326 | 327 | # BizTalk build output 328 | *.btp.cs 329 | *.btm.cs 330 | *.odx.cs 331 | *.xsd.cs 332 | 333 | # OpenCover UI analysis results 334 | OpenCover/ 335 | 336 | # Azure Stream Analytics local run output 337 | ASALocalRun/ 338 | 339 | # MSBuild Binary and Structured Log 340 | *.binlog 341 | 342 | # NVidia Nsight GPU debugger configuration file 343 | *.nvuser 344 | 345 | # MFractors (Xamarin productivity tool) working folder 346 | .mfractor/ 347 | 348 | # Local History for Visual Studio 349 | .localhistory/ 350 | 351 | # BeatPulse healthcheck temp database 352 | healthchecksdb 353 | 354 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 355 | MigrationBackup/ 356 | 357 | # Ionide (cross platform F# VS Code tools) working folder 358 | .ionide/ 359 | 360 | ### DotnetCore ### 361 | # .NET Core build folders 362 | bin/ 363 | obj/ 364 | 365 | # Common node modules locations 366 | /node_modules 367 | /wwwroot/node_modules 368 | 369 | # End of https://www.toptal.com/developers/gitignore/api/dotnetcore,csharp -------------------------------------------------------------------------------- /server/service_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: service.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor.FileDescriptor( 17 | name='service.proto', 18 | package='', 19 | syntax='proto3', 20 | serialized_options=None, 21 | create_key=_descriptor._internal_create_key, 22 | serialized_pb=b'\n\rservice.proto\"9\n\x05Pizza\x12\x10\n\x08toppings\x18\x01 \x03(\t\x12\x0e\n\x06inches\x18\x02 \x01(\x05\x12\x0e\n\x06\x63heese\x18\x03 \x01(\x08\"G\n\x05Order\x12\x16\n\x06pizzas\x18\x01 \x03(\x0b\x32\x06.Pizza\x12\x15\n\rcustomer_name\x18\x02 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x03 \x01(\t\"/\n\x11OrderConfirmation\x12\x1a\n\x12\x65stimated_delivery\x18\x01 \x01(\x03\"\x07\n\x05\x45mpty2V\n\x08Pizzeria\x12\x1b\n\x07IsReady\x12\x06.Empty\x1a\x06.Empty\"\x00\x12-\n\rRegisterOrder\x12\x06.Order\x1a\x12.OrderConfirmation\"\x00\x62\x06proto3' 23 | ) 24 | 25 | 26 | 27 | 28 | _PIZZA = _descriptor.Descriptor( 29 | name='Pizza', 30 | full_name='Pizza', 31 | filename=None, 32 | file=DESCRIPTOR, 33 | containing_type=None, 34 | create_key=_descriptor._internal_create_key, 35 | fields=[ 36 | _descriptor.FieldDescriptor( 37 | name='toppings', full_name='Pizza.toppings', index=0, 38 | number=1, type=9, cpp_type=9, label=3, 39 | has_default_value=False, default_value=[], 40 | message_type=None, enum_type=None, containing_type=None, 41 | is_extension=False, extension_scope=None, 42 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 43 | _descriptor.FieldDescriptor( 44 | name='inches', full_name='Pizza.inches', index=1, 45 | number=2, type=5, cpp_type=1, label=1, 46 | has_default_value=False, default_value=0, 47 | message_type=None, enum_type=None, containing_type=None, 48 | is_extension=False, extension_scope=None, 49 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 50 | _descriptor.FieldDescriptor( 51 | name='cheese', full_name='Pizza.cheese', index=2, 52 | number=3, type=8, cpp_type=7, label=1, 53 | has_default_value=False, default_value=False, 54 | message_type=None, enum_type=None, containing_type=None, 55 | is_extension=False, extension_scope=None, 56 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 57 | ], 58 | extensions=[ 59 | ], 60 | nested_types=[], 61 | enum_types=[ 62 | ], 63 | serialized_options=None, 64 | is_extendable=False, 65 | syntax='proto3', 66 | extension_ranges=[], 67 | oneofs=[ 68 | ], 69 | serialized_start=17, 70 | serialized_end=74, 71 | ) 72 | 73 | 74 | _ORDER = _descriptor.Descriptor( 75 | name='Order', 76 | full_name='Order', 77 | filename=None, 78 | file=DESCRIPTOR, 79 | containing_type=None, 80 | create_key=_descriptor._internal_create_key, 81 | fields=[ 82 | _descriptor.FieldDescriptor( 83 | name='pizzas', full_name='Order.pizzas', index=0, 84 | number=1, type=11, cpp_type=10, label=3, 85 | has_default_value=False, default_value=[], 86 | message_type=None, enum_type=None, containing_type=None, 87 | is_extension=False, extension_scope=None, 88 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 89 | _descriptor.FieldDescriptor( 90 | name='customer_name', full_name='Order.customer_name', index=1, 91 | number=2, type=9, cpp_type=9, label=1, 92 | has_default_value=False, default_value=b"".decode('utf-8'), 93 | message_type=None, enum_type=None, containing_type=None, 94 | is_extension=False, extension_scope=None, 95 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 96 | _descriptor.FieldDescriptor( 97 | name='address', full_name='Order.address', index=2, 98 | number=3, type=9, cpp_type=9, label=1, 99 | has_default_value=False, default_value=b"".decode('utf-8'), 100 | message_type=None, enum_type=None, containing_type=None, 101 | is_extension=False, extension_scope=None, 102 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 103 | ], 104 | extensions=[ 105 | ], 106 | nested_types=[], 107 | enum_types=[ 108 | ], 109 | serialized_options=None, 110 | is_extendable=False, 111 | syntax='proto3', 112 | extension_ranges=[], 113 | oneofs=[ 114 | ], 115 | serialized_start=76, 116 | serialized_end=147, 117 | ) 118 | 119 | 120 | _ORDERCONFIRMATION = _descriptor.Descriptor( 121 | name='OrderConfirmation', 122 | full_name='OrderConfirmation', 123 | filename=None, 124 | file=DESCRIPTOR, 125 | containing_type=None, 126 | create_key=_descriptor._internal_create_key, 127 | fields=[ 128 | _descriptor.FieldDescriptor( 129 | name='estimated_delivery', full_name='OrderConfirmation.estimated_delivery', index=0, 130 | number=1, type=3, cpp_type=2, label=1, 131 | has_default_value=False, default_value=0, 132 | message_type=None, enum_type=None, containing_type=None, 133 | is_extension=False, extension_scope=None, 134 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 135 | ], 136 | extensions=[ 137 | ], 138 | nested_types=[], 139 | enum_types=[ 140 | ], 141 | serialized_options=None, 142 | is_extendable=False, 143 | syntax='proto3', 144 | extension_ranges=[], 145 | oneofs=[ 146 | ], 147 | serialized_start=149, 148 | serialized_end=196, 149 | ) 150 | 151 | 152 | _EMPTY = _descriptor.Descriptor( 153 | name='Empty', 154 | full_name='Empty', 155 | filename=None, 156 | file=DESCRIPTOR, 157 | containing_type=None, 158 | create_key=_descriptor._internal_create_key, 159 | fields=[ 160 | ], 161 | extensions=[ 162 | ], 163 | nested_types=[], 164 | enum_types=[ 165 | ], 166 | serialized_options=None, 167 | is_extendable=False, 168 | syntax='proto3', 169 | extension_ranges=[], 170 | oneofs=[ 171 | ], 172 | serialized_start=198, 173 | serialized_end=205, 174 | ) 175 | 176 | _ORDER.fields_by_name['pizzas'].message_type = _PIZZA 177 | DESCRIPTOR.message_types_by_name['Pizza'] = _PIZZA 178 | DESCRIPTOR.message_types_by_name['Order'] = _ORDER 179 | DESCRIPTOR.message_types_by_name['OrderConfirmation'] = _ORDERCONFIRMATION 180 | DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY 181 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 182 | 183 | Pizza = _reflection.GeneratedProtocolMessageType('Pizza', (_message.Message,), { 184 | 'DESCRIPTOR' : _PIZZA, 185 | '__module__' : 'service_pb2' 186 | # @@protoc_insertion_point(class_scope:Pizza) 187 | }) 188 | _sym_db.RegisterMessage(Pizza) 189 | 190 | Order = _reflection.GeneratedProtocolMessageType('Order', (_message.Message,), { 191 | 'DESCRIPTOR' : _ORDER, 192 | '__module__' : 'service_pb2' 193 | # @@protoc_insertion_point(class_scope:Order) 194 | }) 195 | _sym_db.RegisterMessage(Order) 196 | 197 | OrderConfirmation = _reflection.GeneratedProtocolMessageType('OrderConfirmation', (_message.Message,), { 198 | 'DESCRIPTOR' : _ORDERCONFIRMATION, 199 | '__module__' : 'service_pb2' 200 | # @@protoc_insertion_point(class_scope:OrderConfirmation) 201 | }) 202 | _sym_db.RegisterMessage(OrderConfirmation) 203 | 204 | Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), { 205 | 'DESCRIPTOR' : _EMPTY, 206 | '__module__' : 'service_pb2' 207 | # @@protoc_insertion_point(class_scope:Empty) 208 | }) 209 | _sym_db.RegisterMessage(Empty) 210 | 211 | 212 | 213 | _PIZZERIA = _descriptor.ServiceDescriptor( 214 | name='Pizzeria', 215 | full_name='Pizzeria', 216 | file=DESCRIPTOR, 217 | index=0, 218 | serialized_options=None, 219 | create_key=_descriptor._internal_create_key, 220 | serialized_start=207, 221 | serialized_end=293, 222 | methods=[ 223 | _descriptor.MethodDescriptor( 224 | name='IsReady', 225 | full_name='Pizzeria.IsReady', 226 | index=0, 227 | containing_service=None, 228 | input_type=_EMPTY, 229 | output_type=_EMPTY, 230 | serialized_options=None, 231 | create_key=_descriptor._internal_create_key, 232 | ), 233 | _descriptor.MethodDescriptor( 234 | name='RegisterOrder', 235 | full_name='Pizzeria.RegisterOrder', 236 | index=1, 237 | containing_service=None, 238 | input_type=_ORDER, 239 | output_type=_ORDERCONFIRMATION, 240 | serialized_options=None, 241 | create_key=_descriptor._internal_create_key, 242 | ), 243 | ]) 244 | _sym_db.RegisterServiceDescriptor(_PIZZERIA) 245 | 246 | DESCRIPTOR.services_by_name['Pizzeria'] = _PIZZERIA 247 | 248 | # @@protoc_insertion_point(module_scope) 249 | -------------------------------------------------------------------------------- /server/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "1c4f5c2ce398e241ed0239a73be8c7a2ffa2b51b78647ea40ac557534dca5863" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.8" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "googleapis-common-protos": { 20 | "hashes": [ 21 | "sha256:560716c807117394da12cecb0a54da5a451b5cf9866f1d37e9a5e2329a665351", 22 | "sha256:c8961760f5aad9a711d37b675be103e0cc4e9a39327e0d6d857872f698403e24" 23 | ], 24 | "index": "pypi", 25 | "version": "==1.52.0" 26 | }, 27 | "grpcio": { 28 | "hashes": [ 29 | "sha256:0222ceec7e8dbddd18c6b027214fb3d55b78a823337f95730d4e157b733c5766", 30 | "sha256:04712ec521907b814445f915a834e090352173ede45c6063dfafa64a1e1eb86f", 31 | "sha256:07ed96a6c320505456be2e95edcdcec3e484beff9edaa46bdb6f9e5b88eebc2b", 32 | "sha256:1205bbe8bb41705dec20dc77c51205d05805d785ddae64dbbbbcc8063b7f1550", 33 | "sha256:143028a0421ac0af976a08fbc36de09e14cbdd74d4dc319f914e3511b737c659", 34 | "sha256:1664a3dbd34ab91172149526fb8ba18f626edb72448397280ec6f4d30dc34be4", 35 | "sha256:21077fc89374b3c25377010ca7ddde6287007a6f0a1c515887f43d5ad84dc431", 36 | "sha256:21c235f7f8f3a1fb6db387ffc9ceef38bd4b3f5185b4b6b43065a57fd1fcda20", 37 | "sha256:254a42e13d945c880a8d35a63c646227e691b7c085e433a505fbbaea362bfe1e", 38 | "sha256:47ccf4b6b3ae4fd192500a78af7f191f1c88ee7493744a75657b970b4b17e678", 39 | "sha256:57fb11dcf7d801ccae146f92a07f70545e8f0042354b856ccb9085f39c15564f", 40 | "sha256:5c232df1cea26f53b763d1fc2d28ddef209de2a7fb20efc8d6a19ea47ac61dbb", 41 | "sha256:60765d070dadfce363c74175ff96dbdf5b15f8bcf999bedafc972b938899fd7a", 42 | "sha256:62d2dbc5ab27fe7a33b30ab0395c1c65bf1033cca17e645279420094c99327a1", 43 | "sha256:66c1850ddd8e032655d947d18b56826c942c002e5e9a50b659389cbbb9d557df", 44 | "sha256:6a45081ece2279678f104e40a3683772fc1a917aac5c4352bd0769bd390470e5", 45 | "sha256:6ffe23e3f845ae7058b32f58b252bc367865d44a8c42838e16b5fe5727b174d4", 46 | "sha256:774678e29321fc76bbe01d25e8778fbe96fd2d9fbe774c24a122891b34f53918", 47 | "sha256:7e0029ec181c4d3ca76217f8c8b686b96a583d74b893ac86b514f6c37a74889b", 48 | "sha256:8872620c946733dbc6336243c98440ef4d1b2956578b682c2f67543aef98e815", 49 | "sha256:976f30637bb89b3ca714a3a762c825ef7c4bb38c6b43d7425c02e620ba47ef82", 50 | "sha256:a48518e831573c7592064fb67aab61b33c279c944da2632e5922badb422ce175", 51 | "sha256:a498effc32dd57dfde8d75b266d6656ab2bc0b20188ef3422f060244442c4b39", 52 | "sha256:b20f555557c12f4c7c32f298b8b8202da49902ce008e4c0bdb0a83f8de2355c9", 53 | "sha256:b380f590f28a51f31eaa1c6991b93f5af39158956a0e6bb7ab6fdd3e830055b6", 54 | "sha256:b9e672396fef071ecd4b0ffca59c05d668ddce19a44ef6c253f7d88bbe2ed246", 55 | "sha256:c7ffff3d6c935bf400d329ad33e2326e4917885f1faa3e985eb6bcf43bea88bc", 56 | "sha256:c9dd598f8b96e86f99628fbd615cbab97328557a77f06ad8cd720bc8a2125a8b", 57 | "sha256:ccefa3fc8a1fbed1beac7de64e6b28fa16c4fd224fad90213f9293dcb3ff1c0e", 58 | "sha256:ccf967e1e3d1f62cd63feeecca567511dd321b5b65abfb6c880264295a0e2df7", 59 | "sha256:d3d6f614b5e9c58afc45fbe0383bab206392f2901ebb7fe0027d4abadad7e4e6", 60 | "sha256:d41e2d75f836a0e0e637a7c383d668602063ec655de8bf4b3167b3d1fddabf41", 61 | "sha256:d9ac1cf1633ccc561d7d97ee0af3fbe262a6573c08a8f88cfea58caef1c73505", 62 | "sha256:e2555101f42dda5ca43ccef4a397ba9596a5f7c40dcfed6a81984374c6d60411", 63 | "sha256:e699ddfd287230b8efa6aca3932f7303e587025bdd4122ccbca9134857cca8a2", 64 | "sha256:e88210253bda4c92c22d74d122f43e53e204211b22dc5567367f40ce0197e378", 65 | "sha256:ec7ded77c8644a791fa09ad4d20b258b4b5aff1e4cc62e15e6c4b3a4e19eb898", 66 | "sha256:ef89d99d5fbdd453e52b4193d5cf74f773fafd682dfd87b4fa297dbf20feff50", 67 | "sha256:f19782ec5104599382a0f73f2dfea465d0e65f6818bb3c49ca672b97034c64c3", 68 | "sha256:f2c63017125fbffd70f674fc9988290578c836af7e6bb44f7284ff196af207c9", 69 | "sha256:f34df047f72ec675b61316e9d56904d069f5f9c4172bfee48e3f40d5c8e07df1", 70 | "sha256:f8816e38fbddd31216683a283b48294d7eabd4bf1e26f8cc0cb7bed896f44f30", 71 | "sha256:fb7e9029ec99568519f9a13a9da4e5a83020197ffbfb23a28fe4e58a2c3ae11c", 72 | "sha256:ffc6e264399ac5e48684f33213b086ce7a2163928a41518eca99e1d88c2069b0" 73 | ], 74 | "index": "pypi", 75 | "version": "==1.33.1" 76 | }, 77 | "grpcio-tools": { 78 | "hashes": [ 79 | "sha256:05e4375bde8a092d45d1675fead6e4a7a4c3d96da973187fe4860a75d5b78ff7", 80 | "sha256:1518d42e010953f6b80972d4fc669d529ecdcedf482c7dfbaf876dc6e5eff035", 81 | "sha256:18d985a388b8c1598177dbc36865a040e9c77f2d47b450afa2e92f3e63bca3b0", 82 | "sha256:1c6a611e9ae6ad5d6aa895888c5dc19d970b77fc59f7596ec1d014e328597ce3", 83 | "sha256:1e8110ea510da931160b76d647d54351664e80c027d35cca2bc44ce48ac4eef7", 84 | "sha256:27641f00db36b3f009d21dfb28e405163421a6aa89d30e199f02c6bd58b2616d", 85 | "sha256:2b207e4f013ec1d3afb827de0f319068c916642d41fb66afa92d9144511be836", 86 | "sha256:35f5da1180fdb633a866d2fc12ceebef1e17c3b055621bf94a74404af4c1824c", 87 | "sha256:3b417f2b4041f4805d40d57413654f0302db2cdda1ac6a5745bd0811a8589899", 88 | "sha256:41eb667bb65adc9d4ff28c83d63aee87a0f52568a5fce021767925137874a9c1", 89 | "sha256:474994879abb84de7e13596337321343bfc0e3cc8109c052610a0ad36bb4b877", 90 | "sha256:4c22ab4db29e31c36ef5bd6ae988bd25fa4b858e440d98763132b7be1c35a4e9", 91 | "sha256:5377a03a7690de5202b243ad9f8e2c4e9ca43f0a6b3226c0fd9754877a558ce9", 92 | "sha256:5621f8629a330eddaa239775171228b5cc71781501460ed75709d91e6af2cd77", 93 | "sha256:5f8fb405b3f9bb320c69b88ee2ce7cbc006827bf85c479c8075a0b617b8aaf2a", 94 | "sha256:5fc46d3b5edd33e78d3d8b549eaa9c0fd6737ff18ad8ac3441f843a97e7676a0", 95 | "sha256:6c1d86b547fd9383fe248541d35ae15ddc299e276a0d1312829a3530301b97a5", 96 | "sha256:6dfa887a5e699ea27960013aeae08a9344a28ff95b62a7e43d8d1e7644962601", 97 | "sha256:7211f8b31a14974e75657ea5c968ced90d5952505f6cc7af2324477e0c2247c2", 98 | "sha256:76bc561d02f0d74b0a6487841c43b344ecf599b9f34621ebe6e89b52999f3028", 99 | "sha256:7c770ca893e2d4794c841fa92877f765a33fb5fe17c8a61c6472b3d30b99eafc", 100 | "sha256:8addf3ff710d85a0976b5176b4b612e75ac06a42789d114ee9549540a5ddd29a", 101 | "sha256:94e369783afcaa382825632066239139256ec0f860cfb4cc5f329702a7e9c701", 102 | "sha256:96f52b9e9451ecc922e3fa2e740483ad305e74892c26f15cb450e8e6753439fe", 103 | "sha256:9ac16eac70d9a75241aa3b0c512d38f54a3018c6d08e6de60d4d162a6be63fbc", 104 | "sha256:9b304efa47b6d6cdf73a849270fd189a49100e456733cb7f6d6ab33ae3dbecac", 105 | "sha256:ab37d582689f5d4c10e7fe70cd495fc591556292af71ee15c6f6321ba058e0b9", 106 | "sha256:ad544798cd5d5b259a2619c2a94abe81bcf44ca8fd373190de36ad1c9170ea34", 107 | "sha256:b63131d5a84a7d11d85a426025328ce518575f78997d0285c9e8f1507337bb4a", 108 | "sha256:b86a31260b3cfc151d99ba33393984b65e0d1880e946ffb480577860dfe52621", 109 | "sha256:ba392f73a6da3f7c51f9abae18755ad001ca8ca125736363ccf96636a51a42b8", 110 | "sha256:bbd143d5011dd1c16b158d951dc95b1799c8f86083ada05e2bbe0cec167edd20", 111 | "sha256:c1ad897aa0e3894d2d2e96e7d8a15c9d1b5ac38742a618e0dd38771d89f89ee5", 112 | "sha256:c484ef6c1416edea005dc9b9857c5d5f3ab94f6a54291cc6521d7316a3a4327e", 113 | "sha256:c4da9df7b67541869a01f582d1f37251ebb791622d9e141c4c1a67d66ea57a31", 114 | "sha256:cbad3696066d6e9d818af561dd4da211b3cc652193ba5c95d256c6f6c93e1369", 115 | "sha256:d47820eec86fc40492efa7a85a0869430bbad708be0e0fc0065adb4ebaec8733", 116 | "sha256:db3d50b58465c705c3fce5bc9a309ae98e671effb2097eb8318fe9158b65117f", 117 | "sha256:e569847271bdd1a7fdf72e2fdac794ab299d9eec90ceff430dce42cbc14fde24", 118 | "sha256:e66e44bad421cc7fa63025a9df2f75366f18bfbfe3c6666af7ac324782e23b14", 119 | "sha256:e8d908ff4ddec31a78052513b673aa5a236d7a3c0492feac43db8051d20ecb80", 120 | "sha256:f0a3f0e1c707f328a2eaa64a53675b03ca4f8a8772f6732ee6d81ce2e492d223", 121 | "sha256:fc56027931694be7a2ea45719ef7fed911e2d1dc24ba69d98a418daa78b35467", 122 | "sha256:ffb083da3433056db909b5c2bbf901c438e1655643a758c4f12ff29358b47ea4" 123 | ], 124 | "index": "pypi", 125 | "version": "==1.33.1" 126 | }, 127 | "protobuf": { 128 | "hashes": [ 129 | "sha256:0bba42f439bf45c0f600c3c5993666fcb88e8441d011fad80a11df6f324eef33", 130 | "sha256:1e834076dfef9e585815757a2c7e4560c7ccc5962b9d09f831214c693a91b463", 131 | "sha256:339c3a003e3c797bc84499fa32e0aac83c768e67b3de4a5d7a5a9aa3b0da634c", 132 | "sha256:361acd76f0ad38c6e38f14d08775514fbd241316cce08deb2ce914c7dfa1184a", 133 | "sha256:3dee442884a18c16d023e52e32dd34a8930a889e511af493f6dc7d4d9bf12e4f", 134 | "sha256:4d1174c9ed303070ad59553f435846a2f877598f59f9afc1b89757bdf846f2a7", 135 | "sha256:5db9d3e12b6ede5e601b8d8684a7f9d90581882925c96acf8495957b4f1b204b", 136 | "sha256:6a82e0c8bb2bf58f606040cc5814e07715b2094caeba281e2e7d0b0e2e397db5", 137 | "sha256:8c35bcbed1c0d29b127c886790e9d37e845ffc2725cc1db4bd06d70f4e8359f4", 138 | "sha256:91c2d897da84c62816e2f473ece60ebfeab024a16c1751aaf31100127ccd93ec", 139 | "sha256:9c2e63c1743cba12737169c447374fab3dfeb18111a460a8c1a000e35836b18c", 140 | "sha256:9edfdc679a3669988ec55a989ff62449f670dfa7018df6ad7f04e8dbacb10630", 141 | "sha256:c0c5ab9c4b1eac0a9b838f1e46038c3175a95b0f2d944385884af72876bd6bc7", 142 | "sha256:c8abd7605185836f6f11f97b21200f8a864f9cb078a193fe3c9e235711d3ff1e", 143 | "sha256:d69697acac76d9f250ab745b46c725edf3e98ac24763990b24d58c16c642947a", 144 | "sha256:df3932e1834a64b46ebc262e951cd82c3cf0fa936a154f0a42231140d8237060", 145 | "sha256:e7662437ca1e0c51b93cadb988f9b353fa6b8013c0385d63a70c8a77d84da5f9", 146 | "sha256:f68eb9d03c7d84bd01c790948320b768de8559761897763731294e3bc316decb" 147 | ], 148 | "version": "==3.13.0" 149 | }, 150 | "six": { 151 | "hashes": [ 152 | "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", 153 | "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" 154 | ], 155 | "version": "==1.15.0" 156 | } 157 | }, 158 | "develop": {} 159 | } 160 | -------------------------------------------------------------------------------- /client/Data.cs: -------------------------------------------------------------------------------- 1 | namespace Client 2 | { 3 | 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System; 7 | 8 | public class Toppings 9 | { 10 | 11 | private static readonly Random Random = new Random(); 12 | public static IEnumerable Select(int select) 13 | { 14 | return Values.OrderBy(x => Random.Next()).Take(select); 15 | } 16 | static readonly string[] Values = new string[]{ 17 | "Alfalfa Sprouts", 18 | "Artichoke hearts", 19 | "Avocado", 20 | "Baby leeks", 21 | "Beetroot", 22 | "Black Beans", 23 | "Broccoli", 24 | "Capers", 25 | "Capicolla", 26 | "Carrot", 27 | "Cherry tomatoes", 28 | "Dried tomatoes", 29 | "Eggplant", 30 | "Fungi", 31 | "Fungi carciofi", 32 | "Green peppers", 33 | "Kalamata olives", 34 | "Lettuce", 35 | "Mushrooms", 36 | "Onions", 37 | "Olives", 38 | "Peas", 39 | "Porcini mushrooms", 40 | "Portobello Mushrooms", 41 | "Red beans", 42 | "Red onions", 43 | "Red peppers", 44 | "Roast cauliflower", 45 | "Roasted eggplant", 46 | "Roasted Garlic", 47 | "Roasted peppers", 48 | "scallions", 49 | "Shallots", 50 | "Snow peas", 51 | "Spinach", 52 | "Sun dried tomatoes", 53 | "Sweet corn", 54 | "Watercress", 55 | "Wild mushrooms", 56 | "Yellow peppers", 57 | "Yellow squash", 58 | "Zucchini", 59 | "Almonds", 60 | "Peanuts", 61 | "Pistachios", 62 | "Pecans", 63 | "Pine Nuts", 64 | "Walnuts", 65 | "Basil", 66 | "Bay Leaf", 67 | "Cardamon", 68 | "Chili Dried or Fresh", 69 | "Chives", 70 | "Cilantro", 71 | "Coriander", 72 | "Cumin", 73 | "Dill", 74 | "Garlic", 75 | "Jalapeno Peppers", 76 | "Laurel", 77 | "Marjoram", 78 | "Methi Leaves (aka Fenugreek)", 79 | "Oregano", 80 | "Parley", 81 | "Pepper", 82 | "Rosemary", 83 | "Basil", 84 | "Bay Leaf", 85 | "Cardamon", 86 | "Anchovies", 87 | "Cajun Prawn", 88 | "Crayfish", 89 | "Lobster", 90 | "Oysters", 91 | "Prawns", 92 | "Salmon", 93 | "Shrimps", 94 | "Smoked Salmon", 95 | "Squid", 96 | "Tuna", 97 | "Whitebait", 98 | "Blue Cheese", 99 | "Brie", 100 | "Camembert", 101 | "Chedar", 102 | "Colby", 103 | "Feta", 104 | "Goat Cheese", 105 | "Gorgonzola", 106 | "Limburger", 107 | "Manchego", 108 | "Monterey Jack", 109 | "Parmesan", 110 | "Mozzarella", 111 | "Muenster", 112 | "Port de Salut", 113 | "Provolone", 114 | "Ricota", 115 | "Romano", 116 | "Roquefort", 117 | "Smoked Gouda", 118 | "Bacon", 119 | "BBQ Chicken", 120 | "Beef", 121 | "Cajun Chicken", 122 | "Chicken Masala", 123 | "Chicken Tikka", 124 | "Chorizo", 125 | "Duck", 126 | "Ham", 127 | "Honey Cured Ham", 128 | "Meatballs", 129 | "Pepperoni", 130 | "Proscuitto", 131 | "Salami", 132 | "Sausage", 133 | "Serrano Ham", 134 | "Turkey", 135 | "Venison", 136 | }; 137 | } 138 | 139 | public class Customer 140 | { 141 | public string CustomerName { get; set; } 142 | public string Address { get; set; } 143 | 144 | public static Customer[] Customers = new Customer[] { 145 | new Customer { CustomerName = "Leonard Le", Address = "399-4801 Odio. Street" }, 146 | new Customer { CustomerName = "Anjolie W. Odonnell", Address = "194-4933 Eu Av." }, 147 | new Customer { CustomerName = "Murphy Berger", Address = "319-7370 Vel St." }, 148 | new Customer { CustomerName = "Anika J. Benjamin", Address = "Ap #843-1254 Suspendisse St." }, 149 | new Customer { CustomerName = "Austin E. Horton", Address = "Ap #544-6499 Et Street" }, 150 | new Customer { CustomerName = "Kieran A. Salazar", Address = "Ap #668-930 Ornare Rd." }, 151 | new Customer { CustomerName = "Maggy Trevino", Address = "Ap #191-5732 Non Rd." }, 152 | new Customer { CustomerName = "Blaze Z. Baker", Address = "P.O. Box 573, 8759 Donec St." }, 153 | new Customer { CustomerName = "Calista E. Bradley", Address = "P.O. Box 568, 4854 Lacus. Avenue" }, 154 | new Customer { CustomerName = "Bertha Z. Walls", Address = "P.O. Box 940, 294 Pellentesque St." }, 155 | new Customer { CustomerName = "Quinlan Mcneil", Address = "P.O. Box 391, 2789 Diam Rd." }, 156 | new Customer { CustomerName = "Troy I. Richard", Address = "Ap #666-575 Semper Ave" }, 157 | new Customer { CustomerName = "Griffin Bauer", Address = "P.O. Box 586, 7874 Aliquet Avenue" }, 158 | new Customer { CustomerName = "Faith V. Harrell", Address = "4803 Aliquet St." }, 159 | new Customer { CustomerName = "Octavia D. Andrews", Address = "P.O. Box 566, 2868 Non St." }, 160 | new Customer { CustomerName = "Indigo Bell", Address = "314-5528 Ornare. Avenue" }, 161 | new Customer { CustomerName = "Hunter Rutledge", Address = "P.O. Box 579, 5640 Neque St." }, 162 | new Customer { CustomerName = "Zeph U. Deleon", Address = "487-6921 Egestas St." }, 163 | new Customer { CustomerName = "Daria O. Huffman", Address = "7385 Sit Road" }, 164 | new Customer { CustomerName = "Cruz U. Nixon", Address = "P.O. Box 317, 7382 Curae; Ave" }, 165 | new Customer { CustomerName = "Rafael U. Poole", Address = "P.O. Box 837, 7770 Iaculis Ave" }, 166 | new Customer { CustomerName = "Zenaida Cobb", Address = "3630 Porttitor Street" }, 167 | new Customer { CustomerName = "Emerson C. Sampson", Address = "Ap #808-5449 Eu St." }, 168 | new Customer { CustomerName = "Justin F. Thomas", Address = "835-6511 Non St." }, 169 | new Customer { CustomerName = "Lynn Drake", Address = "P.O. Box 864, 2381 Risus. Road" }, 170 | new Customer { CustomerName = "Beverly Lawson", Address = "Ap #267-1293 Tellus Road" }, 171 | new Customer { CustomerName = "Octavius M. Page", Address = "P.O. Box 415, 8485 Posuere, Road" }, 172 | new Customer { CustomerName = "Illana Lyons", Address = "Ap #311-7689 At, Ave" }, 173 | new Customer { CustomerName = "Beck P. Cross", Address = "148-5963 Id St." }, 174 | new Customer { CustomerName = "Alice Strong", Address = "P.O. Box 438, 9651 Non St." }, 175 | new Customer { CustomerName = "Brenda Roberts", Address = "9042 Convallis Street" }, 176 | new Customer { CustomerName = "Brooke O. Dunlap", Address = "Ap #704-2500 Dictum. Rd." }, 177 | new Customer { CustomerName = "Caesar I. Chambers", Address = "P.O. Box 344, 3592 Convallis Av." }, 178 | new Customer { CustomerName = "Dorothy Lloyd", Address = "529-3123 Justo. Av." }, 179 | new Customer { CustomerName = "Tatum V. Bowen", Address = "6908 Risus. Rd." }, 180 | new Customer { CustomerName = "Daria Guy", Address = "Ap #316-6613 Fermentum Street" }, 181 | new Customer { CustomerName = "Ryder F. Gamble", Address = "8443 Luctus St." }, 182 | new Customer { CustomerName = "Melanie T. Humphrey", Address = "9571 Arcu. Rd." }, 183 | new Customer { CustomerName = "Benjamin Fuentes", Address = "Ap #272-4054 Tincidunt St." }, 184 | new Customer { CustomerName = "Gisela Riddle", Address = "Ap #280-6233 Magna. Ave" }, 185 | new Customer { CustomerName = "Risa Blair", Address = "366-1489 Pede. Rd." }, 186 | new Customer { CustomerName = "Lamar V. Herman", Address = "Ap #883-6658 Sed St." }, 187 | new Customer { CustomerName = "Sierra Hayden", Address = "871-5786 Eros. Avenue" }, 188 | new Customer { CustomerName = "Mona Barron", Address = "407-6395 Vestibulum Av." }, 189 | new Customer { CustomerName = "Nelle J. Hyde", Address = "690-312 Et Road" }, 190 | new Customer { CustomerName = "Sophia S. Donovan", Address = "9665 Egestas Street" }, 191 | new Customer { CustomerName = "Brent Hyde", Address = "179-4068 Donec St." }, 192 | new Customer { CustomerName = "Gary Hodges", Address = "P.O. Box 857, 2408 Nascetur St." }, 193 | new Customer { CustomerName = "Nell S. Kelley", Address = "Ap #570-516 Ligula Rd." }, 194 | new Customer { CustomerName = "Amy Hewitt", Address = "330-5636 Inceptos Road" }, 195 | new Customer { CustomerName = "Ira L. Thompson", Address = "720-4007 Non Road" }, 196 | new Customer { CustomerName = "Sacha X. George", Address = "Ap #869-4814 Id Av." }, 197 | new Customer { CustomerName = "Ann Z. Hobbs", Address = "P.O. Box 227, 575 Dolor Rd." }, 198 | new Customer { CustomerName = "Kevin Chen", Address = "Ap #769-3219 Sagittis Street" }, 199 | new Customer { CustomerName = "James P. Bennett", Address = "P.O. Box 447, 5170 Proin Road" }, 200 | new Customer { CustomerName = "Geoffrey Tyson", Address = "3037 Proin Avenue" }, 201 | new Customer { CustomerName = "Aphrodite A. Trevino", Address = "9228 Sodales Rd." }, 202 | new Customer { CustomerName = "Alexa Davidson", Address = "P.O. Box 515, 5389 Congue. Ave" }, 203 | new Customer { CustomerName = "Knox I. Blair", Address = "Ap #448-4771 Vulputate, St." }, 204 | new Customer { CustomerName = "Eden Rodriguez", Address = "Ap #105-2547 Mollis Ave" }, 205 | new Customer { CustomerName = "Hector W. Gonzales", Address = "P.O. Box 398, 2526 Massa. Road" }, 206 | new Customer { CustomerName = "Rudyard L. Reynolds", Address = "Ap #830-348 Sodales Avenue" }, 207 | new Customer { CustomerName = "Jessamine O. Guy", Address = "162-9284 Hendrerit Avenue" }, 208 | new Customer { CustomerName = "Frances H. Chapman", Address = "264-4099 Fusce Street" }, 209 | new Customer { CustomerName = "Merrill W. Horn", Address = "P.O. Box 379, 514 Proin St." }, 210 | new Customer { CustomerName = "Hanae O. Flowers", Address = "P.O. Box 969, 6925 Molestie Road" }, 211 | new Customer { CustomerName = "Lane Q. Sears", Address = "443-8746 Felis St." }, 212 | new Customer { CustomerName = "Echo H. Meyers", Address = "P.O. Box 626, 149 Risus. Road" }, 213 | new Customer { CustomerName = "Zena Hatfield", Address = "3917 Quisque St." }, 214 | new Customer { CustomerName = "Martena B. Robertson", Address = "P.O. Box 706, 322 Vestibulum Street" }, 215 | new Customer { CustomerName = "Lionel J. Farley", Address = "2284 Vulputate Av." }, 216 | new Customer { CustomerName = "Miriam Frank", Address = "5387 In Ave" }, 217 | new Customer { CustomerName = "Emi C. Ward", Address = "P.O. Box 167, 8846 Vitae Street" }, 218 | new Customer { CustomerName = "Todd X. Maxwell", Address = "706-5890 Vehicula. Road" }, 219 | new Customer { CustomerName = "Joseph I. Sweeney", Address = "637-479 Vitae Av." }, 220 | new Customer { CustomerName = "Shelly Hendricks", Address = "4601 Eget Ave" }, 221 | new Customer { CustomerName = "Cailin O. Larson", Address = "Ap #488-8469 Non St." }, 222 | new Customer { CustomerName = "Nita Wynn", Address = "8972 Suspendisse Avenue" }, 223 | new Customer { CustomerName = "Phelan G. Booker", Address = "Ap #678-6325 Faucibus Rd." }, 224 | new Customer { CustomerName = "Quamar Leach", Address = "P.O. Box 396, 4027 Sit St." }, 225 | new Customer { CustomerName = "Lydia Rosa", Address = "P.O. Box 890, 6518 Dolor Street" }, 226 | new Customer { CustomerName = "Robert E. Stuart", Address = "P.O. Box 141, 637 Malesuada Ave" }, 227 | new Customer { CustomerName = "Petra Moon", Address = "Ap #455-885 Purus, Rd." }, 228 | new Customer { CustomerName = "Myles Zimmerman", Address = "627-1545 Augue St." }, 229 | new Customer { CustomerName = "Tucker Baker", Address = "Ap #339-7718 Justo Ave" }, 230 | new Customer { CustomerName = "Beatrice David", Address = "P.O. Box 631, 8635 Eget Avenue" }, 231 | new Customer { CustomerName = "Angela P. Hewitt", Address = "Ap #483-9692 Magna Road" }, 232 | new Customer { CustomerName = "Pamela X. Rollins", Address = "801 Gravida Ave" }, 233 | new Customer { CustomerName = "Jorden K. Hill", Address = "461-7104 Montes, Street" }, 234 | new Customer { CustomerName = "Driscoll B. Rasmussen", Address = "P.O. Box 174, 2086 Et, Rd." }, 235 | new Customer { CustomerName = "Macaulay Fernandez", Address = "Ap #661-4373 Donec Ave" }, 236 | new Customer { CustomerName = "Colton Ferrell", Address = "7401 Ligula Street" }, 237 | new Customer { CustomerName = "Phillip N. Acosta", Address = "2023 Sem Rd." }, 238 | new Customer { CustomerName = "Ulric Bailey", Address = "597 Ornare Avenue" }, 239 | new Customer { CustomerName = "Courtney D. Boyer", Address = "Ap #724-5162 Fusce Avenue" }, 240 | new Customer { CustomerName = "Haley M. Bates", Address = "876-2714 Interdum. St." }, 241 | new Customer { CustomerName = "Arden Byers", Address = "857-9369 Enim. St." }, 242 | new Customer { CustomerName = "Murphy Nicholson", Address = "Ap #953-3054 Odio, Ave" }, 243 | new Customer { CustomerName = "Timothy J. Buck", Address = "1090 Quis St." }, 244 | new Customer { CustomerName = "Elvis Schmidt", Address = "1685 Duis Ave" } 245 | }; 246 | 247 | } 248 | } --------------------------------------------------------------------------------