-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1af5c30
commit 24710f0
Showing
9 changed files
with
300 additions
and
0 deletions.
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,5 @@ | ||
[run] | ||
omit = | ||
src/nasdaq_protocols/tools/* | ||
|
||
|
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,3 @@ | ||
include src/nasdaq_protocols/common/message/templates/*.mustache | ||
include src/nasdaq_protocols/tools/templates/*.mustache | ||
include src/nasdaq_protocols/tools/templates/*.xml |
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
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,138 @@ | ||
from importlib import resources | ||
from pathlib import Path | ||
|
||
import attrs | ||
import click | ||
import chevron | ||
|
||
from . import templates | ||
|
||
|
||
__all__ = [ | ||
'create' | ||
] | ||
SUPPORTED_PROTOCOLS = ['ouch', 'itch'] | ||
TEMPLATES_PATH = resources.files(templates) | ||
|
||
|
||
@attrs.define(auto_attribs=True) | ||
class AppInfo: | ||
app_name: str | ||
app_dir: Path | ||
app_xml: Path | ||
proto_name: str | ||
|
||
|
||
@attrs.define(auto_attribs=True) | ||
class Context: | ||
project_name: str | ||
project_src_name: str | ||
target_dir: Path | ||
pyproject_toml: Path | ||
tox_ini: Path | ||
apps: list[AppInfo] | ||
|
||
|
||
@click.command() | ||
@click.option( | ||
'--name', '-n', required=True, | ||
help='Project name' | ||
) | ||
@click.option( | ||
'--target-dir', '-d', type=click.Path(), required=False, default='.', | ||
help='Target directory to create the project structure' | ||
) | ||
@click.option( | ||
'--application', '-a', multiple=True, required=True, | ||
help=f'''include applications in this project. | ||
format appname:protocol | ||
e.g. -a oe:ouch -a md:itch -a fix_oe:fix | ||
supported protocols: {SUPPORTED_PROTOCOLS} | ||
''' | ||
) | ||
def create(name, target_dir, application): | ||
try: | ||
_validate_applications(application) | ||
except Exception as e: | ||
raise click.ClickException(str(e)) | ||
|
||
click.echo(f'Creating project {name} in {target_dir}') | ||
|
||
target_dir = Path(target_dir) / Path(name) | ||
context = Context( | ||
project_name=name, | ||
project_src_name=name.replace('-', '_'), | ||
target_dir=Path(target_dir), | ||
pyproject_toml=Path(target_dir) / Path('pyproject.toml'), | ||
tox_ini=Path(target_dir) / Path('tox.ini'), | ||
apps=[] | ||
) | ||
|
||
for app_proto in application: | ||
app_name, proto_name = app_proto.split(':') | ||
app_dir = Path(target_dir) / Path('src') / Path(context.project_src_name) / Path(app_name) | ||
app_info = AppInfo( | ||
app_name=app_name, | ||
app_dir=app_dir, | ||
app_xml=app_dir / Path(f'{app_name}.xml'), | ||
proto_name=proto_name | ||
) | ||
app_info.app_dir.mkdir(parents=True, exist_ok=True) | ||
_write_app_xml(app_info) | ||
click.echo(f'Created application directory: {app_dir}') | ||
context.apps.append(app_info) | ||
|
||
Path(target_dir / Path('__init__.py')).touch() | ||
_write_pyproject(context) | ||
_write_tox(context) | ||
|
||
click.echo(f'Created project {name} in {target_dir}') | ||
|
||
|
||
def _write_app_xml(app_info: AppInfo): | ||
if app_info.app_xml.exists(): | ||
return | ||
|
||
if app_info.proto_name in ['ouch', 'itch']: | ||
xml_template = TEMPLATES_PATH / Path('ouch_itch_xml.mustache') | ||
else: | ||
raise ValueError(f'Unsupported protocol: {app_info.proto_name}') | ||
|
||
with open(app_info.app_xml, 'w', encoding='utf-8') as op, open(xml_template, 'r', encoding='utf-8') as inp: | ||
content = chevron.render(inp.read(), attrs.asdict(app_info), partials_path=str(TEMPLATES_PATH)) | ||
op.write(content) | ||
|
||
|
||
def _write_pyproject(context: Context): | ||
toml_template = TEMPLATES_PATH / Path('toml.mustache') | ||
with (open(context.pyproject_toml, 'a', encoding='utf-8') as op, | ||
open(toml_template, 'r', encoding='utf-8') as inp): | ||
content = chevron.render(inp.read(), attrs.asdict(context), partials_path=str(TEMPLATES_PATH)) | ||
op.write(content) | ||
|
||
|
||
def _write_tox(context: Context): | ||
tox_template = TEMPLATES_PATH / Path('tox.mustache') | ||
with (open(context.tox_ini, 'a', encoding='utf-8') as op, | ||
open(tox_template, 'r', encoding='utf-8') as inp): | ||
content = chevron.render(inp.read(), attrs.asdict(context), partials_path=str(TEMPLATES_PATH)) | ||
op.write(content) | ||
|
||
|
||
def _validate_applications(applications): | ||
apps = {} | ||
for app_proto in applications: | ||
if ':' not in app_proto: | ||
raise ValueError(f'Invalid application protocol: {app_proto}, format = appname:protocol') | ||
|
||
app_name, proto_name = app_proto.split(':') | ||
if app_name in apps: | ||
raise ValueError(f'Application {app_name} already exists') | ||
|
||
if proto_name not in SUPPORTED_PROTOCOLS: | ||
raise ValueError(f'Unsupported protocol: {proto_name} for application: {app_name},' | ||
f' Supported protocols: {SUPPORTED_PROTOCOLS}') | ||
|
||
apps[app_name] = proto_name |
Empty file.
82 changes: 82 additions & 0 deletions
82
src/nasdaq_protocols/tools/templates/ouch_itch_xml.mustache
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,82 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<root> | ||
<enums-root> | ||
<!-- Add your enums here --> | ||
</enums-root> | ||
<messages-root> | ||
<!-- Add your messages here --> | ||
</messages-root> | ||
</root> | ||
|
||
<!-- | ||
ENUM DEFINITION: | ||
<enum id="ENUM_NAME" type="DATATYPE"> | ||
<value name="VALUE1" description="DESCRIPTION1">VALUE1</value> | ||
<value name="VALUE2" description="DESCRIPTION2">VALUE2</value> | ||
</enum> | ||
Example: | ||
<enum id="OuchSide" type="char_iso-8859-1"> | ||
<value name="Buy" description="Buy">B</value> | ||
<value name="Sell" description="Sell">S</value> | ||
</enum> | ||
MESSAGE DEFINITION: | ||
<message id="MESSAGE_NAME" message-id="MSG_TYPE_IN_DECIMAL" direction="incoming | outgoing"> | ||
<fields> | ||
<field name="FIELD_NAME" type="DATATYPE"/> | ||
</fields> | ||
</message> | ||
* The direction indicates the flow of message with respect to the server, | ||
if the message is sent from the server to the client, the direction is 'outgoing' otherwise 'incoming' | ||
* MSG_TYPE_IN_DECIMAL: The message type in decimal, | ||
this is the value that is used to identify the message in the wire. | ||
Use '65' for 'A' and '66' for 'B' and so on. | ||
* If the DATATYPE of the field contains 'n' at the end, | ||
it means the field is a fixed length string and the length is specified in the 'length' attribute | ||
Example: | ||
<message id="EnterOrder" message-id="69" direction="incoming"> | ||
<fields> | ||
<field name="token" type="int_8_be"/> | ||
<field name="book" type="int_4_be"/> | ||
<field name="side" type="char_iso-8859-1"/> | ||
<field name="account" type="str_iso-8859-1_n" length="16"/> | ||
<field name="customerInfo" type="str_iso-8859-1_n" length="15"/> | ||
<field name="exchangeInfo" type="str_iso-8859-1_n" length="32"/> | ||
</fields> | ||
</message> | ||
DATATYPES: | ||
These are the possible data types you can use for fields or enums | ||
boolean: boolean type indicated by b'\x00' or b'\x01' | ||
byte: 1 byte integer | ||
int_2: 2 byte integer in little endian | ||
int_2_be: 2 byte integer in big endian | ||
uint_2: 2 byte unsigned integer in little endian | ||
uint_2_be: 2 byte unsigned integer in big endian | ||
int_4: 4 byte integer in little endian | ||
int_4_be: 4 byte integer in big endian | ||
uint_4: 4 byte unsigned integer in little endian | ||
uint_4_be: 4 byte unsigned integer in big endian | ||
int_8: 8 byte integer in little endian | ||
int_8_be: 8 byte integer in big endian | ||
uint_8: 8 byte unsigned integer in little endian | ||
uint_8_be: 8 byte unsigned integer in big endian | ||
char_ascii: 1 byte ascii character | ||
char_iso-8859-1: 1 byte iso-8859-1 character | ||
str_ascii: ascii string | ||
str_iso-8859-1: iso-8859-1 string | ||
str_ascii_n: ascii string with length 'n' | ||
str_iso-8859-1_n: iso-8859-1 string with length 'n' | ||
--> |
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,53 @@ | ||
[build-system] | ||
requires = ["setuptools>=64", "setuptools_scm[toml]>=8"] | ||
build-backend = "setuptools.build_meta" | ||
|
||
|
||
[project] | ||
name = "{{project_name}}" | ||
description = "Nasdaq protocols python implementation ({{project_name}})" | ||
|
||
# LICENSE | ||
# ADD license here | ||
# uncomment one of the following line if you want to specify the license of the package | ||
# license = { text = "" } | ||
# license = { file = "" } | ||
|
||
|
||
# VERSION | ||
# Comment the following line if you want to use the dynamic versioning based on git tags | ||
version = "0.0.1" | ||
|
||
# DEPENDENCIES | ||
# add your dependencies to the below list | ||
dependencies = [ | ||
'nasdaq-protocols>=0.0.1', | ||
] | ||
|
||
# VERSION | ||
# uncomment the following lines if you want to specify the version of this package to be based on git tag | ||
#dynamic = ["version"] | ||
#[tool.setuptools_scm] | ||
|
||
|
||
# SCRIPTS | ||
# uncomment the following line if you want to specify the scripts of the package | ||
# [project.scripts] | ||
# Add project scripts here | ||
|
||
|
||
[tool.setuptools.packages.find] | ||
where = ["src"] # list of folders that contain the packages (["."] by default) | ||
include = ["{{project_src_name}}*"] # package names should match these glob patterns (["*"] by default) | ||
namespaces = false # to disable scanning PEP 420 namespaces (true by default) | ||
|
||
|
||
# DATA FILES | ||
# uncomment the following line if you want to package the asn1 files. | ||
#[tool.setuptools.package-data] | ||
#{{project_src_name}} = ["*.asn1"] | ||
|
||
|
||
[options] | ||
zip_safe = true | ||
include_package_data = true |
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,18 @@ | ||
[tox] | ||
requires = | ||
tox>4 | ||
virtualenv>20.2 | ||
env_list = | ||
build | ||
|
||
[testenv:build] | ||
description = Build package | ||
deps = | ||
nasdaq-protocols | ||
build | ||
commands = | ||
{{#apps}} | ||
nasdaq-generate-{{proto_name}}-classes src/{{project_src_name}}/{{app_name}}/{{app_name}}.xml src/{{project_src_name}}/{{app_name}} {{app_name}} {{project_src_name}}.{{app_name}} | ||
{{/apps}} | ||
python -m build | ||
|