Browse Source

Initial commit

master
Noah Pederson 2 years ago
parent
commit
7f64d170e5
  1. 2
      .gitignore
  2. 13
      connexion_example/Dockerfile
  3. 55
      connexion_example/app.py
  4. 34
      connexion_example/requirements.txt
  5. 119
      connexion_example/swagger.yaml
  6. 54
      docker-compose.yaml
  7. 12
      nameko_example/Dockerfile.logger_service
  8. 12
      nameko_example/Dockerfile.pet_service
  9. 0
      nameko_example/__init__.py
  10. 14
      nameko_example/config.yaml
  11. 10
      nameko_example/logger_service.py
  12. 70
      nameko_example/pet_service.py
  13. 22
      nameko_example/requirements.txt

2
.gitignore

@ -94,3 +94,5 @@ ENV/
# Rope project settings
.ropeproject
# VS Code
.vscode

13
connexion_example/Dockerfile

@ -0,0 +1,13 @@
FROM python:3.7.2-stretch
MAINTAINER Noah Pederson noah@packetlostandfound.us
EXPOSE 8080
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT python app.py

55
connexion_example/app.py

@ -0,0 +1,55 @@
#!/usr/bin/env python3
import connexion
import datetime
import logging
import os
from connexion import NoContent
from nameko.standalone.rpc import ClusterRpcProxy
# our memory-only pet storage
PETS = {}
config = {
'AMQP_URI': os.environ["AMQP_URI"] #"pyamqp://guest:guest@localhost"
}
def get_pets(limit, animal_type=None):
with ClusterRpcProxy(config) as cluster_rpc:
pets = cluster_rpc.pet_service.get_pets(limit, animal_type=animal_type)
return {"pets": pets}
def get_pet(pet_id):
with ClusterRpcProxy(config) as cluster_rpc:
pet = cluster_rpc.pet_service.retrieve_pet(pet_id)
return pet or ('Not found', 404)
def put_pet(pet_id, pet):
with ClusterRpcProxy(config) as cluster_rpc:
exists = cluster_rpc.pet_service.put_pet(pet_id, pet)
return NoContent, (200 if exists else 201)
def delete_pet(pet_id):
with ClusterRpcProxy(config) as cluster_rpc:
exists = cluster_rpc.pet_service.delete_pet(pet_id)
if exists:
return NoContent, 204
else:
return NoContent, 404
logging.basicConfig(level=logging.INFO)
app = connexion.App(__name__)
app.add_api('swagger.yaml')
# set the WSGI application callable to allow using uWSGI:
# uwsgi --http :8080 -w app
application = app.app
if __name__ == '__main__':
app.run(port=8080)

34
connexion_example/requirements.txt

@ -0,0 +1,34 @@
amqp==2.4.1
certifi==2018.11.29
chardet==3.0.4
Click==7.0
clickclick==1.2.2
connexion==2.2.0
dnspython==1.16.0
eventlet==0.24.1
Flask==1.0.2
greenlet==0.4.15
idna==2.8
importlib-metadata==0.8
inflection==0.3.1
itsdangerous==1.1.0
Jinja2==2.10
jsonschema==2.6.0
kombu==4.3.0
MarkupSafe==1.1.1
mock==2.0.0
monotonic==1.5
nameko==2.11.0
openapi-spec-validator==0.2.6
path.py==11.5.0
pathlib==1.0.1
pbr==5.1.3
PyYAML==3.13
requests==2.21.0
six==1.12.0
swagger-ui-bundle==0.0.3
urllib3==1.24.1
vine==1.2.0
Werkzeug==0.14.1
wrapt==1.11.1
zipp==0.3.3

119
connexion_example/swagger.yaml

@ -0,0 +1,119 @@
swagger: '2.0'
info:
title: Pet Shop Example API
version: "0.1"
description: Simple example API to store and retrieve pets
consumes:
- application/json
produces:
- application/json
paths:
/pets:
get:
tags: [Pets]
operationId: app.get_pets
summary: Get all pets
parameters:
- name: animal_type
in: query
type: string
pattern: "^[a-zA-Z0-9]*$"
- name: limit
in: query
type: integer
format: int32
minimum: 0
default: 100
responses:
200:
description: Return pets
schema:
type: object
properties:
pets:
type: array
items:
$ref: '#/definitions/Pet'
/pets/{pet_id}:
get:
tags: [Pets]
operationId: app.get_pet
summary: Get a single pet
parameters:
- $ref: '#/parameters/pet_id'
responses:
200:
description: Return pet
schema:
$ref: '#/definitions/Pet'
404:
description: Pet does not exist
put:
tags: [Pets]
operationId: app.put_pet
summary: Create or update a pet
parameters:
- $ref: '#/parameters/pet_id'
- name: pet
in: body
schema:
$ref: '#/definitions/Pet'
responses:
200:
description: Pet updated
201:
description: New pet created
delete:
tags: [Pets]
operationId: app.delete_pet
summary: Remove a pet
parameters:
- $ref: '#/parameters/pet_id'
responses:
204:
description: Pet was deleted
404:
description: Pet does not exist
parameters:
pet_id:
name: pet_id
description: Pet's Unique identifier
in: path
type: string
required: true
pattern: "^[a-zA-Z0-9-]+$"
definitions:
Pet:
type: object
required:
- name
- animal_type
properties:
id:
type: string
description: Unique identifier
example: "123"
readOnly: true
name:
type: string
description: Pet's name
example: "Susie"
minLength: 1
maxLength: 100
animal_type:
type: string
description: Kind of animal
example: "cat"
minLength: 1
tags:
type: object
description: Custom tags
created:
type: string
format: date-time
description: Creation time
example: "2015-07-07T15:49:51.230+02:00"
readOnly: true

54
docker-compose.yaml

@ -0,0 +1,54 @@
---
version: "3.7"
services:
rabbitmq:
image: "rabbitmq:3.7.12-management"
expose:
- 5672
- 15672
restart: always
networks:
- nameko
- default
connexion:
build:
dockerfile: Dockerfile
context: ./connexion_example
expose:
- 8080
ports:
- "8080:8080"
environment:
AMQP_URI: "pyamqp://guest:guest@rabbitmq"
restart: always
networks:
- nameko
depends_on:
- rabbitmq
pet_service:
build:
dockerfile: Dockerfile.pet_service
context: ./nameko_example
environment:
AMQP_URI: "pyamqp://guest:guest@rabbitmq"
restart: always
networks:
- nameko
depends_on:
- rabbitmq
logger_service:
build:
dockerfile: Dockerfile.logger_service
context: ./nameko_example
environment:
AMQP_URI: "pyamqp://guest:guest@rabbitmq"
restart: always
networks:
- nameko
depends_on:
- rabbitmq
networks:
nameko:
external: false

12
nameko_example/Dockerfile.logger_service

@ -0,0 +1,12 @@
FROM python:3.7.2-stretch
MAINTAINER Noah Pederson noah@packetlostandfound.us
EXPOSE 8080
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT nameko run --config config.yaml logger_service

12
nameko_example/Dockerfile.pet_service

@ -0,0 +1,12 @@
FROM python:3.7.2-stretch
MAINTAINER Noah Pederson noah@packetlostandfound.us
EXPOSE 8080
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT nameko run --config config.yaml pet_service

0
nameko_example/__init__.py

14
nameko_example/config.yaml

@ -0,0 +1,14 @@
AMQP_URI: ${AMQP_URI}
WEB_SERVER_ADDRESS: '0.0.0.0:8000'
rpc_exchange: 'nameko-rpc'
max_workers: 10
parent_calls_tracked: 10
LOGGING:
version: 1
handlers:
console:
class: logging.StreamHandler
root:
level: DEBUG
handlers: [console]

10
nameko_example/logger_service.py

@ -0,0 +1,10 @@
from nameko.events import event_handler, SINGLETON
class LoggerService:
name = "system_logger"
@event_handler("pet_service", "log", handler_type=SINGLETON, reliable_delivery=True)
def handle_pet_service_log(self, message):
logging.info(message)
print(message)

70
nameko_example/pet_service.py

@ -0,0 +1,70 @@
from nameko.rpc import rpc
from nameko.events import EventDispatcher, event_handler, SINGLETON
import datetime
import logging
pets = {
"1": {
"id": "1",
"name": "Freya",
"animal_type": "cat",
"tags": None,
"created": datetime.datetime.utcnow()
},
"2": {
"id": "2",
"name": "Satyr",
"animal_type": "cat",
"tags": None,
"created": datetime.datetime.utcnow()
},
"3": {
"id": "3",
"name": "Bogie",
"animal_type": "dog",
"tags": None,
"created": datetime.datetime.utcnow()
}
}
class PetService:
name = "pet_service"
dispatch = EventDispatcher()
@rpc
def get_pets(self, limit, animal_type=None):
self.dispatch("log", f"Recevied request to list all pets with anime_type {animal_type}")
return [pet for pet in pets.values() if not animal_type or pet['animal_type'] == animal_type][:limit]
@rpc
def retrieve_pet(self, pet_id):
self.dispatch("log", f"Received request to retrieve pet with id {pet_id}")
if pet_id in pets:
return pets[pet_id]
else:
msg = f"Pet with pet_id {pet_id} not found"
self.dispatch("log", msg)
# Explicitly raise the exception here so we can control the message
raise KeyError(msg)
@rpc
def put_pet(self, pet_id, pet):
self.dispatch("log", f"Inserting new pet with id {pet_id}")
if pet_id in pets:
self.dispatch("log", f"Updating pet with id {pet_id}")
pets[pet_id].update(pet)
return True
else:
self.dispatch("log", f"Creating pet with id {pet_id}")
pets[pet_id] = pet
return False
@rpc
def delete_pet(self, pet_id):
self.dispatch("log", f"Deleting pet with id {pet_id}")
exists = pet_id in pets
del pets[pet_id]
return exists

22
nameko_example/requirements.txt

@ -0,0 +1,22 @@
amqp==2.4.1
certifi==2018.11.29
chardet==3.0.4
dnspython==1.16.0
eventlet==0.24.1
greenlet==0.4.15
idna==2.8
importlib-metadata==0.8
kombu==4.3.0
mock==2.0.0
monotonic==1.5
nameko==2.11.0
path.py==11.5.0
pbr==5.1.3
PyYAML==3.13
requests==2.21.0
six==1.12.0
urllib3==1.24.1
vine==1.2.0
Werkzeug==0.14.1
wrapt==1.11.1
zipp==0.3.3
Loading…
Cancel
Save