-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add python Client (#65) * feat: ci and documentation for python client (#69) * fix: add missing self for builder * fix: header usage in example * added type hints for better warnings during type mismatch * added test for checking headers * added formatting * reduce python requirement to 3.9 --------- Co-authored-by: Ravi Suhag <[email protected]>
- Loading branch information
1 parent
d8a60ef
commit 9d8f2c1
Showing
35 changed files
with
1,252 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Release Client - Python | ||
|
||
on: | ||
release: | ||
types: [published] | ||
workflow_dispatch: | ||
|
||
jobs: | ||
publish-python-client: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: '3.11' | ||
- name: Install Poetry | ||
uses: snok/install-poetry@v1 | ||
- name: Install dependencies | ||
working-directory: clients/python | ||
run: poetry install --with=dev | ||
- name: Build | ||
working-directory: clients/python | ||
run: | | ||
poetry version $(cat ../../version.txt) | ||
poetry publish --build -u $PYPI_USERNAME -p $PYPI_PASSWORD --dry-run | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
name: Test Raccoon Python Client | ||
on: | ||
push: | ||
paths: | ||
- "clients/python/**" | ||
branches: | ||
- main | ||
pull_request: | ||
paths: | ||
- "clients/python/**" | ||
jobs: | ||
format-python: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: '3.11' | ||
- name: Install Poetry | ||
uses: snok/install-poetry@v1 | ||
- name: Install dependencies | ||
working-directory: clients/python | ||
run: poetry install --with=dev | ||
- name: Format | ||
working-directory: clients/python | ||
run: poetry run python -m black . --check | ||
lint-python: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: '3.11' | ||
- name: Install Poetry | ||
uses: snok/install-poetry@v1 | ||
- name: Install dependencies | ||
working-directory: clients/python | ||
run: poetry install --with=dev | ||
- name: Lint | ||
working-directory: clients/python | ||
run: | | ||
poetry run python -m ruff check raccoon_client tests | ||
poetry run python -m pylint raccoon_client tests | ||
test-python: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python 3.11 | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: '3.11' | ||
- name: Install Poetry | ||
uses: snok/install-poetry@v1 | ||
- name: Install dependencies | ||
working-directory: clients/python | ||
run: poetry install | ||
- name: Unit Test | ||
working-directory: clients/python | ||
run: poetry run python -m unittest discover -p '*_test.py' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Python Client | ||
|
||
### Setup | ||
- The project uses poetry for build, and virutal env management. | ||
- The client was created with 3.11 as it's python environment. Hence 3.11 can be considered it's minimum requirement. It's also stated in the pyproject.toml file. | ||
- Make sure to install poetry via https://python-poetry.org/docs/#installing-manually | ||
- After installing poetry you can activate the env by `poetry env use` | ||
- Install all dependencies using `poetry install --no-root --with=dev` (no-root tells that the package is not at the root of the directory) | ||
- For setting up in IDE, make sure to setup the interpreter to use the virtual environment that was created when you activated poetry env. | ||
|
||
### Lint and Formatting | ||
- We use black for formatting of python files and pylint, ruff for linting the python files. | ||
- You can check the command for running lint and formating by referring to `test-python-client.yml` workflow. | ||
|
||
### Usage | ||
- You can use the raccoon by installing it from PyPi by the following command | ||
- From Pypi | ||
```pip install raccoon_client``` | ||
- From Github | ||
```pip install raccoon_client@git+https://github.com/raystack/raccoon@$VERSION#subdirectory=clients/python``` | ||
where $VERSION is a git tag. | ||
- An example on how to use the client is under the [examples](examples) package. | ||
|
||
### Confiugration | ||
The client supports the following configuration: | ||
|
||
| Name | Description | Type | Default | | ||
|---------|-----------------------------------------------------------------------------------|-----------------------------------|---------| | ||
| url | The remote server url to connect to | string | "" | | ||
| retries | The max number of retries to be attempted before an event is considered a failure | int (<10) | 3 | | ||
| timeout | The number of seconds to wait before timing out the request | float | 1.0 | | ||
| serialiser | The format to which event field of client.Event serialises it's data to | Serialiser Enum(JSON or PROTOBUF) | JSON | | ||
|wire_type | The format in which the request payload should be sent to server | Wire Type Enum(JSON or PROTOBUF) | JSON | | ||
| headers | HTTP header key value pair to be sent along with each request | dict | {} | | ||
|
||
|
||
Note: | ||
- During development, make sure to open just the python directory, otherwise the IDE misconfigures the imports. | ||
- The protos package contain generated code and should not be edited manually. | ||
- It's recommended not to use JSON serialiser, when using proto generated classes as your events due to JSON encoding incompatibility. [Issue](https://github.com/raystack/raccoon/issues/67) | ||
|
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from raccoon_client.client import Event | ||
from raccoon_client.protos.raystack.raccoon.v1beta1.raccoon_pb2 import SendEventRequest | ||
from raccoon_client.rest.client import RestClient | ||
from raccoon_client.rest.option import RestClientConfigBuilder | ||
from raccoon_client.serde.enum import Serialiser, WireType | ||
|
||
|
||
def example_json_serialiser_json_wire(): | ||
event_data = {"a": "field a", "b": "field b"} | ||
|
||
config = ( | ||
RestClientConfigBuilder() | ||
.with_url("http://localhost:8080/api/v1/events") | ||
.with_serialiser(Serialiser.JSON) | ||
.with_wire_type(WireType.JSON) | ||
.build() | ||
) # other parameters supported by the config builder can be checked in its method definition. | ||
rest_client = RestClient(config) | ||
topic_to_publish_to = "test_topic_2" | ||
e = Event(topic_to_publish_to, event_data) | ||
req_id, response, raw = rest_client.send([e]) | ||
return req_id, response, raw | ||
|
||
|
||
def example_protobuf_serialiser_protobuf_wire(): | ||
event_data = ( | ||
SendEventRequest() | ||
) # sample generated proto class which is an event to send to raccoon | ||
event_data.sent_time = 1000 | ||
event_data.req_guid = "some string" | ||
|
||
config = ( | ||
RestClientConfigBuilder() | ||
.with_url("http://localhost:8080/api/v1/events") | ||
.with_serialiser(Serialiser.PROTOBUF) | ||
.with_wire_type(WireType.PROTOBUF) | ||
.with_timeout(10.0) | ||
.with_retry_count(3) | ||
.with_headers({"Authorization": "TOKEN"}) | ||
.build() | ||
) # other parameters supported by the config builder can be checked in its method definition. | ||
rest_client = RestClient(config) | ||
topic_to_publish_to = "test_topic_2" | ||
e = Event(topic_to_publish_to, event_data) | ||
req_id, response, raw = rest_client.send([e]) | ||
return req_id, response, raw | ||
|
||
|
||
def example_protobuf_serialiser_json_wire(): | ||
event_data = ( | ||
SendEventRequest() | ||
) # sample generated proto class which is an event to send to raccoon | ||
event_data.sent_time = 1000 | ||
event_data.req_guid = "some string" | ||
|
||
config = ( | ||
RestClientConfigBuilder() | ||
.with_url("http://localhost:8080/api/v1/events") | ||
.with_serialiser(Serialiser.PROTOBUF) | ||
.with_wire_type(WireType.JSON) | ||
.build() | ||
) # other parameters supported by the config builder can be checked in its method definition. | ||
rest_client = RestClient(config) | ||
topic_to_publish_to = "test_topic_2" | ||
e = Event(topic_to_publish_to, event_data) | ||
req_id, response, raw = rest_client.send([e]) | ||
return req_id, response, raw | ||
|
||
|
||
if __name__ == "__main__": | ||
example_json_serialiser_json_wire() | ||
example_protobuf_serialiser_protobuf_wire() | ||
example_protobuf_serialiser_json_wire() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
[tool.poetry] | ||
name = "raccoon-client" | ||
version = "v0.2.1" | ||
description = "A python client to serve requests to raccoon server" | ||
authors = ["Punit Kulal <[email protected]>"] | ||
readme = "README.md" | ||
packages = [{include = "raccoon_client"}] | ||
|
||
[tool.poetry.dependencies] | ||
python = "^3.9" | ||
requests = "^2.31.0" | ||
protobuf = "^4.23.4" | ||
google = "^3.0.0" | ||
|
||
[tool.poetry.group.dev.dependencies] | ||
requests = "^2.31.0" | ||
black = "^23.7.0" | ||
pylint = "^2.17.5" | ||
ruff = "^0.0.285" | ||
|
||
[build-system] | ||
requires = ["poetry-core"] | ||
build-backend = "poetry.core.masonry.api" | ||
|
||
[tool.black] | ||
line-length = 88 | ||
extend-exclude = '.*_pb2.py|.*_pb2.pyi' | ||
|
||
[tool.ruff] | ||
ignore = ["E501"] | ||
|
||
[tool.pylint.'MESSAGES CONTROL'] | ||
disable = [ | ||
'no-name-in-module', | ||
'line-too-long', | ||
'missing-module-docstring', | ||
'bad-indentation', | ||
'missing-class-docstring', | ||
'missing-function-docstring', | ||
'protected-access' | ||
] | ||
|
||
[tool.pylint.MASTER] | ||
ignore-patterns = '.*_pb2.py|.*_pb2.pyi' |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from dataclasses import dataclass | ||
|
||
from raccoon_client.protos.raystack.raccoon.v1beta1.raccoon_pb2 import ( | ||
SendEventResponse, | ||
) | ||
|
||
|
||
@dataclass | ||
class RaccoonResponseError(IOError): | ||
def __init__(self, status_code, msg): | ||
super().__init__(msg) | ||
self.status_code = status_code | ||
|
||
|
||
@dataclass | ||
class Event: | ||
type: str | ||
event: object | ||
|
||
|
||
class Client: # pylint: disable=too-few-public-methods | ||
def send(self, events: [Event]) -> (str, SendEventResponse, RaccoonResponseError): | ||
raise NotImplementedError() |
Empty file.
Empty file.
Empty file.
Empty file.
42 changes: 42 additions & 0 deletions
42
clients/python/raccoon_client/protos/raystack/raccoon/v1beta1/raccoon_pb2.py
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.