First of all, if you write from the conclusion, you can do something like the figure below.
This is an example of executing the program written in TypeScript displayed on the upper side from the Python program on the lower side.
It uses a library called jsii to convert ** TypeScript programs into Python-executable libraries **. As the official documentation says the magic happens
, it's a magical technique.
jsii can be used in languages such as Java in addition to Python, but in this article, a program written in TypeScript will be executed in Python.
Let's actually do it.
You can use jsii roughly in the following flow.
As a sample, write an appropriate FizzBuzz program in lib / index.ts
with TypeScript.
lib/index.ts
export class MyClass {
fizzBuzz(arg: number): string {
if (arg % (3 * 5) === 0) {
return 'FizzBuzz';
} else if (arg % 3 === 0) {
return 'Fizz';
} else if (arg % 5 === 0) {
return 'Buzz';
}
return arg.toString();
}
}
If you want to check the operation by executing it normally as TypeScript, execute it by your favorite method such as $ npx ts-node lib / index.ts
.
jsii uses the information of package.json
at build time to register the meta information for the library of each language. Therefore, jsii cannot be operated unless package.json
is written" properly "to some extent.
The following is a setting example.
package.json
{
"name": "jsii-example",
"version": "1.0.0",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"author": "your_name",
"repository": {
"url": "https://example.com",
"type": "Git"
},
"license": "MIT",
"jsii": {
"outdir": "dist",
"targets": {
"python": {
"distName": "your_name.jsii_example",
"module": "your_name.jsii_example"
}
}
},
"devDependencies": {
"jsii": "^0.20.6",
"jsii-pacmak": "^0.20.6"
}
}
As mentioned above, the parts that are usually omitted such as repository
and ʻauthorare required when using jsii. Also,
main and
typesmust be specified in the same directory as
lib / index.ts`.
In addition, as a jsii-specific setting, describe the information for each language package in the place called jsii
. This time, in order to build the Python package, the module name information is described as python
in targets
.
Install the packages required to run the jsii
build.
$ npm install --save-dev jsii jsii-pacmak
$ echo "jsii
wheel
publication" > requirements.txt
$ pip install --require requirements.txt
After the above installation is completed, build with the jsii
command and package with the jsii-pacmak
command.
$ npx jsii
$ npx jsii-pacmak
It is successful if your_name.jsii_example-1.0.0.tar.gz
is created in the dist / python
directory.
Install the package file you just created as a Python library.
$ pip install dist/python/your_name.jsii_example-1.0.0.tar.gz
Import this library and write a Python program that calls the fizzBuzz function.
python.py
import your_name.jsii_example
obj = your_name.jsii_example.MyClass()
print(obj.fizz_buzz(2))
print(obj.fizz_buzz(3))
print(obj.fizz_buzz(5))
print(obj.fizz_buzz(15))
It's finally time to run.
$ python python.py
2
Fizz
Buzz
FizzBuzz
I was able to call code written in TypeScript from Python!
Since the execution environment construction described so far requires installation of multiple languages, it is a little troublesome, so this time we have prepared a Dockerfile that can prepare Python and Node.js necessary for executing jsii
together.
FROM python:3.7.5-slim
ENV DIR /app
WORKDIR $DIR
RUN apt update && apt install -y nodejs npm
# setup python
COPY requirements.txt $DIR
RUN pip install --requirement requirements.txt
# setup node
COPY package.json $DIR
RUN npm install
# main: lib/index.ts
COPY lib/ $DIR/lib
After preparing the above package.json
, requirements.txt
, lib / index.ts
, use it as follows.
$ mkdir dist
$ docker build --tag jsii-example .
$ docker run --rm --volume $(pwd)/dist:/app/dist jsii-example /bin/bash -c 'npx jsii && npx jsii-pacmak'
It is successful if the package file is generated under dist /
.
The mechanism of jsii is explained in the jsii documentation. jsii/runtime-architecture.md at master · aws/jsii
When the host code such as Python reaches the place where jsii is used, it seems that the child process of node is started, the program is executed, and the result is received by Python. If you look in the / tmp
directory on your host, you'll find evidence of a temporary npm install of the program.
The documentation also states that ** performance is sacrificed ** because processing that originally ends in Python also depends on communication with Node.js. It is difficult for jsii to operate in applications that require performance such as production environments, and it is expected to be used in development and build tools.
jsii is an OSS developed by AWS. As an actual usage example, jsii is used in AWS CDK, which is an Infrastructure as Code tool provided by AWS. Like jsii, aws-cdk allows you to write infrastructure configurations in TypeScript, Python, .NET, and Java.
Quoted from Frequently Asked Questions about AWS Cloud Development
AWS builds the business logic of the AWS Construct library package in TypeScript and provides mappings to each supported programming language. This ensures that AWS CDK constructs behave consistently across different languages and can provide a comprehensive set of construct packages available in all languages. All code created in the AWS CDK project is native to your preferred programming language. The JavaScript runtime is a detailed implementation of your programming experience. You can find the jsii project at https://github.com/aws/jsii.
Tips
--There are restrictions on TypeScript that can be executed with jsii
--To give an easy-to-understand example, if you try to use reserved words in other languages in TypeScript, they may not work properly.
--Other restrictions are described in the documentation.
- jsii/typescript-restrictions.md at master · aws/jsii
--Not compatible with Python 3.8
--This article runs on Python 3.7.5. When using 3.8.0, an error occurs at the time of writing this article and the library made with jsii cannot be executed.
--There is also an issue
- Python 3.8.0: ImportError: cannot import name '_Union' from 'typing' · Issue #913 · aws/jsii
--Ruby support is under development
--Although it is not clearly stated in the document, if you read the History and the source code, you will find some descriptions that seem to be compatible with Ruby.
--If you specify ruby
in targets
in package.json, jsii
works properly and a package-like file is generated indist / ruby /
, but TypeScript source code is used as it is. Programs to include just seems to be running and gem generation is implemented Is not ...
--There is an issue regarding Ruby support
- Ruby support · Issue #144 · aws/jsii
Using jsii, I was able to execute a program written in TypeScript within the Python source code. Although it is still under development and has many restrictions, it has a certain future because it is actually used in AWS CDK. If you want to use a tool created with one code base from multiple languages, I think this jsii is an option.
The program used this time is also posted on GitHub. If you are interested, please have a look. https://github.com/s2terminal/jsii-example
Recommended Posts