Skip to main content

Inter-Service communication framework, support for microservice architecture and distributed system via http

Project description

Microservices Connector

Microservices Connector is a Inter-Service communication framework, support for microservice architecture and distributed system.

Getting Started

Microservices is a way of breaking large software projects into loosely coupled modules, which communicate with each other through simple APIs. The advantages of microservices are improves fault isolation, scalability, Ease of development. It convinced some big enterprise players – like Amazon, Netflix, and eBay – to begin their transitions.

Microservices Connector is a Inter-Service communication framework written in python, support for microservice architecture and distributed system. Its features contain: * Transfering data as returning a function results or quering data. * Support transfer multiple values with many type as string, int, float, list, dict, class attribute * Do not require knowledge about web/http connection or touch to them * Distributed system

alt text Illustration of network system. Source:medium.com

As illustration, distributed systems are very stable and Infinite scalability. But distributed systems are the most difficult to maintain

Quickstart:

Microservices Connector is available on pip. You can install via pip (require python>=3.5):

pip install microservices_connector

Start project by a minimum example:

  • Step 1: Create 1 file name app1.py, write and save with the code below

from microservices_connector.Interservices import Microservice

M = Microservice(__name__)

@M.typing('/helloworld')
@M.reply
def helloworld(name):
    return 'Welcome %s' % (name)

if __name__ == '__main__':
    M.run()
  • Step 2: Create 1 file name app2.py, write and save with the code below ``` from microservices_connector.Interservices import Friend

F = Friend(‘app1’, ‘http://0.0.0.0:5000’) message = F.send(‘/helloworld’,’Mr. Developer’) print(message)

* Step 3: Run app1.py and app2.py together.

Open a terminal in the same folder with them and run:
`python app1.py`.

Open another terminal in the same folder and run:
`python app2.py`

You get the result: `Welcome Mr. Developer` in terminal of app2.py. This is no difference if you do `from .app1 import helloword; message = helloworld('Mr. Developer'); print(message)`. Note: To stop app1, open its terminal and Ctrl + C. The example can be found in `test/example00` folder

**Explanation**: App1 and app2 are small example of microservice system. In the example, **M** in app1 is listener, a http server while __F__ in app2 is sender. Listener and sender are isolated design, they can work seperately or together in an app/service. A microservice can be a listener of many other microservices or sender of many other microservices or both of them. A standard microservice mention in this project contain both listener and sender.

## Tutorial

### 1. Start your first app

In the tutorial, we assume you have this code in the top of your file.

from microservices_connector.Interservices import Microservice

M = Microservice(name)

Now, look closer at `Microservice(__name__)`, it actually look like this:

    Microservice(name, port: int=5000, host: str='0.0.0.0', debug=None, token: dict = {}, secretKey=None)

Arguments:
* name {str} -- Require a name for your app, recommend put `__name__` for it
* port {int} -- Choose from 3000 to 9000, default to 5000
* host {str} -- Host ip, Default 0.0.0.0 for localhost
* debug {boolean} -- True for development, False/None for production
* token {dict} -- A dict contain all rule and its token. It can be set later

The class Microservice is used to create a listener/a microservice. In a file/app, you should only have one listener. About parameters, If you aren't familiar with http server, you only need remember:
* One app should have only one listener
* Should use `__name__` for name and name need to be unique
* If you run multiple listener, use only one unique port for each listener. for example:

M1 = Microservice(name, port=5010) # in file app1 M2 = Microservice(name, port=5020) # in file app2

Note: You should be carefully if there are other web applications running in your port/server.

### 2. Way of running an app

A sender is a python def, so you can put it anywhere in your app. Listener is a http server so it's a bit difference from other.

Option 1: Use if/main in the end of startup file (file that you start your project by `python <filename>`). Add the following code the end:

M is your Microservice Object

if name == ‘main’: M.run()

Option 2: Create a file name run.py and run your app from this file. For example, we create a run.py in the same folder of app1.py in the first example. It will be like this:

from app1 import M

if name == ‘main’: M.run(port=5000, host=’0.0.0.0’, debug=True)

Option 2 is more appreciated. It avoid the app looping from them self, so get away of stunning your app. If you have 2 app in a server/computer, you should create 2 run file for it. Don't for get `Ctrl + C` to stop your app.

Note: _We assume you already use one of the options above for your code_. This tutorial focuses on communication between 'service-to-service' as def function, not http connect.

### 3. Send, Typing and reply

Think like a human, if you want to communicate with some friend in facebook, you will open *messenger*, find your friend and send a message to them. It's a way of sending message to each other. Then, your friend will type a message and reply you. The process is similar here. See the code:

F = Friend(‘Corgi’, ‘http://0.0.0.0:5000’) # this is: you’re finding friend in your head. # You can call him with a cute name like ‘Puppy’,’Teddy’ or ‘Corgi’. # But you must always remember his real-name is ‘http://0.0.0.0:5000’ to know actually who he is

message = F.send(‘/helloworld’,’Mr. Close friend’) # then you can send him a message

`/helloworld` is the rule/topic you say/ask to a friend or the route in http. It need to start with `/`. The rule must match with the rule of `Typing` to be replied. `Mr. Close friend` is what you are talking about, which can be string, integer, float, list, dict or class.

In other side, your friend or a microservice or a listener has the following process:

@M.typing(‘/helloworld’) # this is the rule/topic he knows. If he don’t know, he cannot reply @M.reply # he is replying def helloworld(name): # this is the process in side his head return ‘Welcome %s’ % (name) # the answer

`@M.typing` - The rule/topic must exactly match with the topic was sent and should startwith "/". The `@M.reply` must come before def. Then, Microservice handles the remain. Next chapter is about returning data

### 4. Send and reply string, integer, float

In the sender side, you can send data type as the code below:

print( “””############################## Test return string “””) F = Friend(‘app1’, ‘http://localhost:5000’) print(‘Test: return a simple string’) x = F.send(‘/str’, ‘A variable value’, key=’A keyword variable value’) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return multiple string’) x, y, z = F.send(‘/str2’, ‘A variable value’, key=’A keyword variable value’) print(‘x=’ ,x, type(x)) print(‘y=’, y, type(y)) print(‘z=’, z, type(z))

print( “””############################## Test return a int, float “””) F = Friend(‘app1’, ‘http://localhost:5000’) print(‘Test: return a simple Value’) x = F.send(‘/int’, 2018, key=312) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return a simple Value’) x = F.send(‘/float’, 2.018, key=3.12) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return multiple Value’) x, y, z = F.send(‘/int3’, 3.1427, key=1000000000) print(‘x=’, x, type(x)) print(‘y=’, y, type(y)) print(‘z=’, z, type(z))

In the listener, you can reply/return data type as string, integer, float as below:

run a normal function in python

print(‘one cat here’)

return string

@M.typing(‘/str’) @M.reply def string1(a,key): return a+’-‘+key

return multiple string

@M.typing(‘/str2’) @M.reply def string2(a, key): return a, key, a+’-‘+key

return Integer and float

@M.typing(‘/int’) @M.reply def int1(a, key): return a+key

@M.typing(‘/float’) @M.reply def float2(a, key): return a+key

@M.typing(‘/int3’) @M.reply def int3(a, key): return a+key, keykey, aa

After that, first run listener then run sender. We have results (see example01):

Test: return a simple string x= A variable value-A keyword variable value ========================== Test: return multiple string x= A variable value y= A keyword variable value z= A variable value-A keyword variable value ‘testStr’ 23.17 ms Test: return a simple Value x= 2330 ========================== Test: return a simple Value x= 5.138 ========================== Test: return multiple Value x= 1000000003.1427 y= 1000000000000000000 z= 9.87656329

Note: print('one cat here') print in the screen of listener

### 5. Send and reply list, dict, class attribute

In the sender side, you can send data type as the code below:

print( “””############################## Test return a list, dict “””) F = Friend(‘app1’, ‘http://localhost:5000’) print(‘Test: return a simple Value’) x = F.send(‘/list’, [12,34,45], key=[‘abc’,’zyz’]) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return a simple Value’) x = F.send(‘/dict’, {‘keyword’:[‘anything’]}, key={‘int’:20,’str’:’adfafsa’,’float’:0.2323}) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return multiple Value’) x, y, z = F.send(‘/list3’, {‘keyword’: [‘anything’]}, key=[‘abc’, ‘zyz’]) print(‘x=’, x, type(x)) print(‘y=’, y, type(y)) print(‘z=’, z, type(z))

print( “””############################## Test return NoneType, Class, use of Token “””) F = Friend(‘app1’, ‘http://localhost:5000’) print(‘Test: return a simple Value’) x = F.send(‘/None’, [12, 34, 45], key=[‘abc’, ‘zyz’]) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return a simple Value with token’) F.setRule(‘/class’, token=’123456’) x = F.send(‘/class’, {‘keyword’: [‘anything’]}, key={‘int’: 20, ‘str’: ‘adfafsa’, ‘float’: 0.2323}) print(‘x=’, x, type(x)) print(‘==========================’) print(‘Test: return multiple Value’) F.setRule(‘/class2’, token=’123456’) x,y,z = F.send(‘/class2’, {‘keyword’: [‘anything’]}, key={‘int’: 20, ‘str’: ‘adfafsa’, ‘float’: 0.2323}) print(‘x=’, x, type(x)) print(‘y=’, y, type(y)) print(‘z=’, z, type(z))

In the listener, you can reply/return data type as string, integer, float as below:

test return list and dict

@M.typing(‘/list’) @M.reply def list1(a, key): a.extend(key) return a

@M.typing(‘/dict’) @M.reply def dict1(a, key): key[‘dict’] = a return key

@M.typing(‘/list3’) @M.reply def list3(a, key): key.append(‘other value’) c = None return a, key, c

return None, class Object

@M.typing(‘/None’) @M.reply def TestNoneValue(a, key): key.append(‘Do something in the server’)

class testservice(object): name = ‘test’ Purpose = ‘For test only’ empty = None def init(self, value): self.value = value

def onemethod(self):
    pass

@M.typing(‘/class’,token=’123456’) @M.reply def TestClass(a, key): t = testservice(a) return t

@M.typing(‘/class2’, token=’123456’) @M.reply def TestClass2(a, key): t = testservice(key) return t, a, None

After that, first run listener then run sender. We have results (for full example see tests/example01):

Test: return a simple Value x= [12, 34, 45, ‘abc’, ‘zyz’] ========================== Test: return a simple Value x= {‘dict’: {‘keyword’: [‘anything’]}, ‘float’: 0.2323, ‘int’: 20, ‘str’: ‘adfafsa’} ========================== Test: return multiple Value x= {‘keyword’: [‘anything’]} y= [‘abc’, ‘zyz’, ‘other value’] z= None ‘testListDict’ 22.19 ms ############################## Test return NoneType, Class, use of Token

Test: return a simple Value x= None ========================== Test: return a simple Value with token x= {‘Purpose’: ‘For test only’, ‘empty’: None, ‘name’: ‘test’, ‘value’: {‘keyword’: [‘anything’]}} ========================== Test: return multiple Value x= {‘Purpose’: ‘For test only’, ‘empty’: None, ‘name’: ‘test’, ‘value’: {‘float’: 0.2323, ‘int’: 20, ‘str’: ‘adfafsa’}} y= {‘keyword’: [‘anything’]} z= None ‘testClassType’ 19.20 ms ``` ## Authors

Favourite idioms: * Don’t repeat your self * Think like human, make for human * Simple is stronger ## License: BDS license

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

microservices_connector-0.1.2.tar.gz (10.0 kB view details)

Uploaded Source

Built Distribution

microservices_connector-0.1.2-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file microservices_connector-0.1.2.tar.gz.

File metadata

File hashes

Hashes for microservices_connector-0.1.2.tar.gz
Algorithm Hash digest
SHA256 be8397ec1fbf2ecbbba4fe40b95313aea0ef659f177d64049a49ccad63d6b4ce
MD5 f5a28349b010e8f768d7341d1297fa77
BLAKE2b-256 9f22de3f923a4c055c8d6c03fb69cbbf78be97d9ae6800e23c13e5360da196f4

See more details on using hashes here.

File details

Details for the file microservices_connector-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for microservices_connector-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c18793b273b29503c846dab16481fcbf2a1434186c438877344bff12a7bc8491
MD5 68571108b7699cb418f902bce5f60c1c
BLAKE2b-256 c809248dc3376e0a8438df0417ec97cccb3e462a5ed46915caceef0de2c45aa1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page