Skip to content

Commit 451942d

Browse files
committed
first commit
0 parents  commit 451942d

File tree

91 files changed

+38151
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+38151
-0
lines changed

.github/workflows/test.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Python LocalStack Client / Run Test
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- .github/workflows/test.yml
7+
- localstack-sdk/**
8+
push:
9+
branches:
10+
- main
11+
12+
jobs:
13+
14+
test_python:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
- name: Set up Python 3.11
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.11"
25+
26+
- name: Update pip
27+
run: |
28+
python -m pip install --upgrade pip
29+
30+
- name: Install project
31+
run: |
32+
make install-dev
33+
34+
- name: Install LocalStack
35+
run: |
36+
pip install --pre --upgrade localstack
37+
38+
- name: Pull image
39+
run: |
40+
docker pull localstack/localstack-pro
41+
42+
- name: Start Localstack
43+
env:
44+
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
45+
run: |
46+
source .venv/bin/activate
47+
DEBUG=1 DISABLE_EVENTS="1" IMAGE_NAME="localstack/localstack-pro:latest" localstack start -d
48+
localstack wait -t 120 || (python -m localstack.cli.main logs && false)
49+
50+
- name: Run Python Tests
51+
env:
52+
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
53+
run: |
54+
make test
55+
56+
- name: Stop Localstack
57+
if: always()
58+
run: |
59+
source .venv/bin/activate
60+
localstack logs
61+
localstack stop

.gitignore

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
*.pyc
2+
*.pyo
3+
*.log
4+
*.keys.json
5+
/nosetests.xml
6+
/.venv*
7+
*/.venv*
8+
*/.mypy_cache
9+
.settings/
10+
.project
11+
.classpath
12+
.coverage*
13+
.DS_Store
14+
/build/
15+
dist/
16+
*.egg-info/
17+
.eggs/
18+
*.sw*
19+
~*
20+
*~
21+
.idea/
22+
*.iml
23+
.vscode/
24+
25+
node_modules/
26+
app/build
27+
package-lock.json
28+
29+
.serverless
30+
31+
target/
32+
33+
testdata/
34+
35+
etc/docker/lambda/*.tmp
36+
etc/docker/lambda/Dockerfile
37+
etc/docker/lambda/entrypoint.sh
38+
39+
*.crt
40+
!localstack-pro-azure/localstack/pro/azure/server/proxy/ca.crt
41+
42+
backend_states/
43+
api_states/
44+
.python_packages/
45+
46+
terraform.tfstate*
47+
.terraform*
48+
**/terraform/tfplan
49+
.env
50+
51+
# test resources
52+
metastore_db/
53+
parity-metrics/
54+
.pytest-report.xml
55+
*.raw.snapshot.json
56+
localstack-pro-azure/visited_urls.csv
57+
localstack-pro-azure/implemented_features.csv
58+
localstack-pro-azure/tests/otherlangs/scripts/website/.azure/config
59+
60+
# dotnet files
61+
localstack-pro-azure/tests/otherlangs/dotnet/*/bin
62+
localstack-pro-azure/tests/otherlangs/dotnet/*/obj
63+
64+
# setuptools_scm version.py
65+
*/*/*/*/version.py
66+
localstack-sdk-python-2/.openapi-generator/

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
VENV_CMD ?= python3 -m venv
2+
VENV_DIR ?= .venv
3+
VENV_BIN = python3 -m venv
4+
VENV_RUN = . $(VENV_DIR)/bin/activate
5+
VENV_ACTIVATE = $(VENV_DIR)/bin/activate
6+
TEST_PATH ?= .
7+
TEST_EXEC ?= python -m
8+
PYTEST_LOGLEVEL ?= warning
9+
PIP_CMD ?= pip
10+
11+
venv: $(VENV_ACTIVATE) ## Create a new (empty) virtual environment
12+
13+
$(VENV_ACTIVATE): localstack-sdk-python/pyproject.toml
14+
test -d $(VENV_DIR) || $(VENV_BIN) $(VENV_DIR)
15+
$(VENV_RUN); $(PIP_CMD) install --upgrade pip
16+
touch $(VENV_ACTIVATE)
17+
18+
install: venv #
19+
$(VENV_RUN); $(PIP_CMD) install -r ./localstack-sdk-generated/requirements.txt
20+
$(VENV_RUN); pip install -e ./localstack-sdk-generated
21+
$(VENV_RUN); pip install -e ./localstack-sdk-python
22+
23+
install-dev: install
24+
$(VENV_RUN); pip install -e ./localstack-sdk-python[test]
25+
26+
build-spec: ## build the entire localstack api spec (openapi.yaml in the root folder)
27+
$(VENV_RUN); python scripts/create_spec.py
28+
29+
clean: ## Clean up
30+
rm -rf $(VENV_DIR)
31+
32+
clean-generated: ## Cleanup generated code
33+
rm -rf localstack-sdk-generated/localstack/generated
34+
35+
format: ## Run ruff to format the whole codebase
36+
($(VENV_RUN); python -m ruff format .; python -m ruff check --output-format=full --exclude localstack-sdk/localstack/generated --fix .)
37+
38+
lint:
39+
($(VENV_RUN); python -m ruff check --exclude localstack-sdk/localstack/generated --output-format=full . && python -m ruff format --exclude localstack-sdk/localstack/generated --check .)
40+
41+
test: ## Run automated tests
42+
($(VENV_RUN); $(TEST_EXEC) pytest --durations=10 --log-cli-level=$(PYTEST_LOGLEVEL) $(PYTEST_ARGS) $(TEST_PATH))
43+
44+
.PHONY: venv clean

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# LocalStack Python SDK
2+
3+
This repository is a PoC for generating a Python SDK for the LocalStack public endpoint.
4+
5+
### Generate the spec
6+
7+
The first step is to generate the `openapi.yaml` spec.
8+
We have a script in `scripts/create_spec.py`
9+
- [ ] todo: fix the script; make sure it also fetches ext spec;
10+
`localstack-core` and `localstack-ext` are part of the dev dependencies for this very step.
11+
12+
### Generate the code
13+
We use openapi-generator from `openapitools`.
14+
To run the generation, run `./bin/generate.sh`.
15+
The script uses the docker image of the CLI and use the `openapi.yaml` file as input.
16+
By default, the generator creates a bunch of files, but the most important things are:
17+
- `api` package: with the all APIs categorized by tags;
18+
- `models` package: with the methods derived from the components or the inline specs;
19+
- [ ] the code from the inline components is much uglier, but we can overwrite some naming with come config (or move to components).
20+
21+
The python generator by default creates 3 functions for each path:
22+
- a normal function (the name is taken from the `operationId` in the specs) just with the validated response payload;
23+
- a function suffixed by `without_preloaded_content`: where the JSON responses are not validated;
24+
- a function suffixed by `with_http_info` which also returns the response header and status.
25+
26+
The code in these `api` files (but also in any other generated artifacts), can be modified by providing custom mustache templates.
27+
[These](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator/src/main/resources/python) are the
28+
default for Python.
29+
Templates are not super immediate, but looking at them and at the generated code you can do it.
30+
For instance, I deleted the `without_preloaded_content` and `with_http_info` generated functions.
31+
32+
### Supporting files
33+
The generated code uses some supporting files, i.e., some utilities that are responsible of making the actual HTTP calls,
34+
validating and parsing the responses.
35+
I just checked in this code and take it as granted, but I am pretty sure we can come up with some simpler code and avoid
36+
to generate this part (would move out from `generated`).
37+
- [ ] see if I can write my own api client and all the necessary supporting code.
38+
39+
### TODO
40+
- [ ] understand if this can be viable at all;
41+
- [ ] devise a way to update the spec automatically and regenerate every time the code in `generated`;
42+
- much more...fill this list up

bin/generate.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
4+
-i /local/openapi.yaml \
5+
--skip-validate-spec \
6+
-g python \
7+
-o /local/localstack-sdk-generated \
8+
--global-property models,apis,supportingFiles \
9+
-p packageName=localstack \
10+
--template-dir /local/localstack-sdk-generated/templates \
11+
--global-property apiTests=false,modelTests=false \
12+
--global-property apiDocs=false,modelDocs=False
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# PyInstaller
28+
# Usually these files are written by a python script from a template
29+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30+
*.manifest
31+
*.spec
32+
33+
# Installer logs
34+
pip-log.txt
35+
pip-delete-this-directory.txt
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.coverage.*
42+
.cache
43+
nosetests.xml
44+
coverage.xml
45+
*,cover
46+
.hypothesis/
47+
venv/
48+
.venv/
49+
.python-version
50+
.pytest_cache
51+
52+
# Translations
53+
*.mo
54+
*.pot
55+
56+
# Django stuff:
57+
*.log
58+
59+
# Sphinx documentation
60+
docs/_build/
61+
62+
# PyBuilder
63+
target/
64+
65+
#Ipython Notebook
66+
.ipynb_checkpoints
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
.github/workflows/python.yml
5+
.gitlab-ci.yml
6+
.travis.yml
7+
git_push.sh
8+
README.md
9+
tox.ini
10+
localstack/__init__.py
11+
pyproject.toml
12+
setup.py
13+
setup.cfg
14+
test-requirements.txt
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
.gitignore
2+
localstack/api/__init__.py
3+
localstack/api/aws_api.py
4+
localstack/api/chaos_api.py
5+
localstack/api/default_api.py
6+
localstack/api/localstack_api.py
7+
localstack/api/pods_api.py
8+
localstack/api/pro_api.py
9+
localstack/api/state_api.py
10+
localstack/api_client.py
11+
localstack/api_response.py
12+
localstack/configuration.py
13+
localstack/exceptions.py
14+
localstack/models/__init__.py
15+
localstack/models/cloud_watch_metrics.py
16+
localstack/models/cloud_watch_metrics_metrics_inner.py
17+
localstack/models/cloud_watch_metrics_metrics_inner_d_inner.py
18+
localstack/models/cloud_watch_metrics_metrics_inner_d_inner_v.py
19+
localstack/models/cloud_watch_metrics_metrics_inner_t.py
20+
localstack/models/cloud_watch_metrics_metrics_inner_v.py
21+
localstack/models/create_remote_request.py
22+
localstack/models/delete_ddb_expired_items200_response.py
23+
localstack/models/fault_rule.py
24+
localstack/models/fault_rule_error.py
25+
localstack/models/get_diagnostics200_response.py
26+
localstack/models/get_diagnostics200_response_logs.py
27+
localstack/models/get_diagnostics200_response_version.py
28+
localstack/models/get_diagnostics200_response_version_host.py
29+
localstack/models/get_diagnostics200_response_version_image_version.py
30+
localstack/models/get_diagnostics200_response_version_localstack_version.py
31+
localstack/models/get_features_and_services200_response.py
32+
localstack/models/get_lambda_runtimes200_response.py
33+
localstack/models/get_remote200_response.py
34+
localstack/models/get_ses_messages200_response.py
35+
localstack/models/get_sns_messages200_response.py
36+
localstack/models/get_sns_sms_messages200_response.py
37+
localstack/models/get_sns_subscription_token200_response.py
38+
localstack/models/init_scripts.py
39+
localstack/models/init_scripts_completed.py
40+
localstack/models/init_scripts_scripts_inner.py
41+
localstack/models/init_scripts_stage.py
42+
localstack/models/init_scripts_stage_scripts_inner.py
43+
localstack/models/list_remotes200_response.py
44+
localstack/models/list_remotes200_response_remotes_inner.py
45+
localstack/models/localstack_pods_environment_get200_response.py
46+
localstack/models/localstack_stackinfo_get200_response.py
47+
localstack/models/manage_session_request.py
48+
localstack/models/network_effects_config.py
49+
localstack/models/pod_list.py
50+
localstack/models/pod_list_cloudpods_inner.py
51+
localstack/models/pod_save_request.py
52+
localstack/models/pod_versions.py
53+
localstack/models/pod_versions_versions_inner.py
54+
localstack/models/remote_config.py
55+
localstack/models/remote_config_one_of.py
56+
localstack/models/ses_sent_email.py
57+
localstack/models/ses_sent_email_body.py
58+
localstack/models/session_info.py
59+
localstack/models/sns_subscription_token_error.py
60+
localstack/models/state_result.py
61+
localstack/models/store_data200_response.py
62+
localstack/models/update_config_option200_response.py
63+
localstack/models/update_config_option_request.py
64+
localstack/py.typed
65+
localstack/rest.py
66+
requirements.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.9.0-SNAPSHOT
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# flake8: noqa
2+
3+
# import apis into api package
4+
from localstack.api.aws_api import AwsApi
5+
from localstack.api.chaos_api import ChaosApi
6+
from localstack.api.default_api import DefaultApi
7+
from localstack.api.localstack_api import LocalstackApi
8+
from localstack.api.pods_api import PodsApi
9+
from localstack.api.pro_api import ProApi
10+
from localstack.api.state_api import StateApi
11+

0 commit comments

Comments
 (0)