stackport 0.4.6__tar.gz → 0.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. stackport-0.4.7/PKG-INFO +443 -0
  2. stackport-0.4.7/README.md +407 -0
  3. stackport-0.4.7/backend/aws_client.py +136 -0
  4. stackport-0.4.7/backend/aws_emulator.py +164 -0
  5. stackport-0.4.7/backend/aws_errors.py +283 -0
  6. {stackport-0.4.6 → stackport-0.4.7}/backend/cli.py +4 -2
  7. {stackport-0.4.6 → stackport-0.4.7}/backend/config.py +50 -1
  8. stackport-0.4.7/backend/connection.py +287 -0
  9. stackport-0.4.7/backend/emulators.py +407 -0
  10. {stackport-0.4.6 → stackport-0.4.7}/backend/endpoint_store.py +115 -20
  11. stackport-0.4.7/backend/error_handlers.py +75 -0
  12. {stackport-0.4.6 → stackport-0.4.7}/backend/main.py +53 -28
  13. stackport-0.4.7/backend/origins.py +160 -0
  14. stackport-0.4.7/backend/routes/common.py +68 -0
  15. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/dynamodb.py +3 -3
  16. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/endpoints.py +89 -101
  17. stackport-0.4.7/backend/routes/lambda_svc.py +533 -0
  18. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/resources.py +2 -2
  19. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/s3.py +5 -6
  20. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/sqs.py +2 -2
  21. stackport-0.4.7/backend/routes/stats.py +332 -0
  22. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/endpoints.py +45 -3
  23. {stackport-0.4.6 → stackport-0.4.7}/backend/websocket.py +20 -56
  24. {stackport-0.4.6 → stackport-0.4.7}/pyproject.toml +1 -1
  25. stackport-0.4.7/stackport.egg-info/PKG-INFO +443 -0
  26. {stackport-0.4.6 → stackport-0.4.7}/stackport.egg-info/SOURCES.txt +57 -40
  27. stackport-0.4.7/tests/test_aws_client_tls.py +157 -0
  28. stackport-0.4.7/tests/test_aws_emulator.py +170 -0
  29. stackport-0.4.7/tests/test_aws_errors.py +157 -0
  30. {stackport-0.4.6 → stackport-0.4.7}/tests/test_cli.py +24 -0
  31. stackport-0.4.7/tests/test_connection.py +267 -0
  32. stackport-0.4.7/tests/test_emulators.py +684 -0
  33. {stackport-0.4.6 → stackport-0.4.7}/tests/test_endpoint_store.py +2 -2
  34. stackport-0.4.7/tests/test_endpoint_store_env.py +136 -0
  35. {stackport-0.4.6 → stackport-0.4.7}/tests/test_endpoints.py +1 -0
  36. stackport-0.4.7/tests/test_endpoints_tls.py +173 -0
  37. stackport-0.4.7/tests/test_error_handlers.py +134 -0
  38. stackport-0.4.7/tests/test_lambda_code_download.py +735 -0
  39. {stackport-0.4.6 → stackport-0.4.7}/tests/test_lambda_routes.py +5 -1
  40. {stackport-0.4.6 → stackport-0.4.7}/tests/test_multi_endpoint.py +9 -9
  41. {stackport-0.4.6 → stackport-0.4.7}/tests/test_readonly_middleware.py +58 -0
  42. stackport-0.4.7/tests/test_request_safety.py +214 -0
  43. {stackport-0.4.6 → stackport-0.4.7}/tests/test_routes.py +1 -1
  44. {stackport-0.4.6 → stackport-0.4.7}/tests/test_sqs_routes.py +102 -0
  45. stackport-0.4.7/tests/test_stats_probe.py +280 -0
  46. stackport-0.4.6/ui/dist/assets/CloudscapeAbout-xEYYjNc3.js → stackport-0.4.7/ui/dist/assets/CloudscapeAbout-C464xiLP.js +1 -1
  47. stackport-0.4.7/ui/dist/assets/CloudscapeDashboard--Puj8I6B.js +1 -0
  48. stackport-0.4.6/ui/dist/assets/CloudscapeLearn-urCq-68_.js → stackport-0.4.7/ui/dist/assets/CloudscapeLearn-CT7ucW_g.js +1 -1
  49. stackport-0.4.7/ui/dist/assets/CloudscapeResourceBrowser-BR6m7Ajg.css +1 -0
  50. stackport-0.4.7/ui/dist/assets/CloudscapeResourceBrowser-CprDqhcQ.js +19 -0
  51. stackport-0.4.7/ui/dist/assets/CloudscapeSettings-DI0pOcAA.css +1 -0
  52. stackport-0.4.7/ui/dist/assets/CloudscapeSettings-D_9KUPvP.js +1 -0
  53. stackport-0.4.7/ui/dist/assets/CloudscapeShell-BCyqqtsn.js +195 -0
  54. stackport-0.4.7/ui/dist/assets/CloudscapeShell-oIMuVycJ.css +1 -0
  55. stackport-0.4.7/ui/dist/assets/ServiceStatus-KR6X2qeu.js +1 -0
  56. stackport-0.4.6/ui/dist/assets/StateMachineGraph-BUugvvkt.js → stackport-0.4.7/ui/dist/assets/StateMachineGraph-D9IP3035.js +1 -1
  57. stackport-0.4.7/ui/dist/assets/index-CHdSsqYw.js +1 -0
  58. stackport-0.4.7/ui/dist/assets/index-CvtAnA9F.js +67 -0
  59. stackport-0.4.7/ui/dist/assets/index-DKnYLurL.js +1 -0
  60. stackport-0.4.6/ui/dist/assets/index-Vf0UFiCT.css → stackport-0.4.7/ui/dist/assets/index-D__irddE.css +1 -1
  61. stackport-0.4.7/ui/dist/assets/index-RwoKZF4y.css +1 -0
  62. stackport-0.4.7/ui/dist/assets/index-WNsJzp13.js +1 -0
  63. stackport-0.4.7/ui/dist/assets/index-WR8pyfQO.js +1 -0
  64. stackport-0.4.7/ui/dist/assets/utils-Dm4tJbJR.js +1 -0
  65. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/index.html +2 -2
  66. stackport-0.4.6/PKG-INFO +0 -385
  67. stackport-0.4.6/README.md +0 -349
  68. stackport-0.4.6/backend/aws_client.py +0 -63
  69. stackport-0.4.6/backend/routes/common.py +0 -63
  70. stackport-0.4.6/backend/routes/lambda_svc.py +0 -238
  71. stackport-0.4.6/backend/routes/stats.py +0 -196
  72. stackport-0.4.6/stackport.egg-info/PKG-INFO +0 -385
  73. stackport-0.4.6/ui/dist/assets/CloudscapeDashboard-dcDZ2KOc.js +0 -1
  74. stackport-0.4.6/ui/dist/assets/CloudscapeResourceBrowser-CzwePG-V.css +0 -1
  75. stackport-0.4.6/ui/dist/assets/CloudscapeResourceBrowser-kEGPuGi-.js +0 -19
  76. stackport-0.4.6/ui/dist/assets/CloudscapeSettings-BbsHquP5.js +0 -1
  77. stackport-0.4.6/ui/dist/assets/CloudscapeShell-BXHVWjDE.css +0 -1
  78. stackport-0.4.6/ui/dist/assets/CloudscapeShell-uZ1fljIL.js +0 -195
  79. stackport-0.4.6/ui/dist/assets/index-CRIgpz3m.js +0 -1
  80. stackport-0.4.6/ui/dist/assets/index-CSPxY-pb.js +0 -67
  81. stackport-0.4.6/ui/dist/assets/index-CghKQufp.js +0 -1
  82. stackport-0.4.6/ui/dist/assets/index-D1zKGwv5.js +0 -1
  83. stackport-0.4.6/ui/dist/assets/index-DE--A2EE.css +0 -1
  84. stackport-0.4.6/ui/dist/assets/index-DcDSxjm9.js +0 -1
  85. stackport-0.4.6/ui/dist/assets/index-DrkkXAoG.css +0 -1
  86. stackport-0.4.6/ui/dist/assets/index-DsTSmMDp.js +0 -1
  87. stackport-0.4.6/ui/dist/assets/utils-Cfmwk2UT.js +0 -1
  88. {stackport-0.4.6 → stackport-0.4.7}/LICENSE +0 -0
  89. {stackport-0.4.6 → stackport-0.4.7}/MANIFEST.in +0 -0
  90. {stackport-0.4.6 → stackport-0.4.7}/backend/__init__.py +0 -0
  91. {stackport-0.4.6 → stackport-0.4.7}/backend/cache.py +0 -0
  92. {stackport-0.4.6 → stackport-0.4.7}/backend/learn/__init__.py +0 -0
  93. {stackport-0.4.6 → stackport-0.4.7}/backend/learn/content.py +0 -0
  94. {stackport-0.4.6 → stackport-0.4.7}/backend/learn/hotspots.py +0 -0
  95. {stackport-0.4.6 → stackport-0.4.7}/backend/learn/trails/aws-first-steps.json +0 -0
  96. {stackport-0.4.6 → stackport-0.4.7}/backend/learn/verify.py +0 -0
  97. {stackport-0.4.6 → stackport-0.4.7}/backend/learn_store.py +0 -0
  98. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/__init__.py +0 -0
  99. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/ec2.py +0 -0
  100. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/iam.py +0 -0
  101. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/kms.py +0 -0
  102. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/learn.py +0 -0
  103. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/logs.py +0 -0
  104. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/monitoring.py +0 -0
  105. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/rds.py +0 -0
  106. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/secretsmanager.py +0 -0
  107. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/sns.py +0 -0
  108. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/stepfunctions.py +0 -0
  109. {stackport-0.4.6 → stackport-0.4.7}/backend/routes/tags.py +0 -0
  110. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/__init__.py +0 -0
  111. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/dynamodb.py +0 -0
  112. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/lambda_svc.py +0 -0
  113. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/learn.py +0 -0
  114. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/logs.py +0 -0
  115. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/monitoring.py +0 -0
  116. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/s3.py +0 -0
  117. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/secretsmanager.py +0 -0
  118. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/sns.py +0 -0
  119. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/sqs.py +0 -0
  120. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/stepfunctions.py +0 -0
  121. {stackport-0.4.6 → stackport-0.4.7}/backend/schemas/tags.py +0 -0
  122. {stackport-0.4.6 → stackport-0.4.7}/setup.cfg +0 -0
  123. {stackport-0.4.6 → stackport-0.4.7}/stackport.egg-info/dependency_links.txt +0 -0
  124. {stackport-0.4.6 → stackport-0.4.7}/stackport.egg-info/entry_points.txt +0 -0
  125. {stackport-0.4.6 → stackport-0.4.7}/stackport.egg-info/requires.txt +0 -0
  126. {stackport-0.4.6 → stackport-0.4.7}/stackport.egg-info/top_level.txt +0 -0
  127. {stackport-0.4.6 → stackport-0.4.7}/tests/test_cache.py +0 -0
  128. {stackport-0.4.6 → stackport-0.4.7}/tests/test_client.py +0 -0
  129. {stackport-0.4.6 → stackport-0.4.7}/tests/test_config.py +0 -0
  130. {stackport-0.4.6 → stackport-0.4.7}/tests/test_create_resources.py +0 -0
  131. {stackport-0.4.6 → stackport-0.4.7}/tests/test_dynamodb_routes.py +0 -0
  132. {stackport-0.4.6 → stackport-0.4.7}/tests/test_ec2_routes.py +0 -0
  133. {stackport-0.4.6 → stackport-0.4.7}/tests/test_iam_routes.py +0 -0
  134. {stackport-0.4.6 → stackport-0.4.7}/tests/test_kms_routes.py +0 -0
  135. {stackport-0.4.6 → stackport-0.4.7}/tests/test_learn_content.py +0 -0
  136. {stackport-0.4.6 → stackport-0.4.7}/tests/test_learn_routes.py +0 -0
  137. {stackport-0.4.6 → stackport-0.4.7}/tests/test_learn_store.py +0 -0
  138. {stackport-0.4.6 → stackport-0.4.7}/tests/test_logs_routes.py +0 -0
  139. {stackport-0.4.6 → stackport-0.4.7}/tests/test_logs_tail.py +0 -0
  140. {stackport-0.4.6 → stackport-0.4.7}/tests/test_monitoring_routes.py +0 -0
  141. {stackport-0.4.6 → stackport-0.4.7}/tests/test_rds_routes.py +0 -0
  142. {stackport-0.4.6 → stackport-0.4.7}/tests/test_registries.py +0 -0
  143. {stackport-0.4.6 → stackport-0.4.7}/tests/test_s3_routes.py +0 -0
  144. {stackport-0.4.6 → stackport-0.4.7}/tests/test_s3_upload_limit_env.py +0 -0
  145. {stackport-0.4.6 → stackport-0.4.7}/tests/test_secretsmanager_routes.py +0 -0
  146. {stackport-0.4.6 → stackport-0.4.7}/tests/test_sns_routes.py +0 -0
  147. {stackport-0.4.6 → stackport-0.4.7}/tests/test_tags_routes.py +0 -0
  148. {stackport-0.4.6 → stackport-0.4.7}/tests/test_websocket.py +0 -0
  149. /stackport-0.4.6/ui/dist/assets/index-DNBdeKId.css → /stackport-0.4.7/ui/dist/assets/ServiceStatus-DNBdeKId.css +0 -0
  150. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/assets/index-DKIdXFX0.css +0 -0
  151. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/assets/index-DoY0HscW.css +0 -0
  152. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/assets/stepfunctions-graph-B6nvU4OB.js +0 -0
  153. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/acm.svg +0 -0
  154. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/apigateway.svg +0 -0
  155. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/appsync.svg +0 -0
  156. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/athena.svg +0 -0
  157. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/cloudformation.svg +0 -0
  158. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/cloudfront.svg +0 -0
  159. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/cognito-idp.svg +0 -0
  160. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/dynamodb.svg +0 -0
  161. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/ec2.svg +0 -0
  162. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/ecr.svg +0 -0
  163. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/ecs.svg +0 -0
  164. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/elasticache.svg +0 -0
  165. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/elasticfilesystem.svg +0 -0
  166. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/elasticloadbalancing.svg +0 -0
  167. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/elasticmapreduce.svg +0 -0
  168. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/events.svg +0 -0
  169. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/firehose.svg +0 -0
  170. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/glue.svg +0 -0
  171. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/iam.svg +0 -0
  172. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/kinesis.svg +0 -0
  173. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/kms.svg +0 -0
  174. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/lambda.svg +0 -0
  175. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/logs.svg +0 -0
  176. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/monitoring.svg +0 -0
  177. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/rds.svg +0 -0
  178. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/route53.svg +0 -0
  179. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/s3.svg +0 -0
  180. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/secretsmanager.svg +0 -0
  181. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/ses.svg +0 -0
  182. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/sns.svg +0 -0
  183. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/sqs.svg +0 -0
  184. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/ssm.svg +0 -0
  185. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/stepfunctions.svg +0 -0
  186. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/aws-icons/wafv2.svg +0 -0
  187. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/favicon.png +0 -0
  188. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/favicon.svg +0 -0
  189. {stackport-0.4.6 → stackport-0.4.7}/ui/dist/stackport-logo.svg +0 -0
@@ -0,0 +1,443 @@
1
+ Metadata-Version: 2.4
2
+ Name: stackport
3
+ Version: 0.4.7
4
+ Summary: Universal AWS resource browser for local emulators
5
+ Author: Davi Reis Vieira
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/DaviReisVieira/stackport
8
+ Project-URL: Repository, https://github.com/DaviReisVieira/stackport
9
+ Project-URL: Issues, https://github.com/DaviReisVieira/stackport/issues
10
+ Keywords: aws,ministack,floci,localstack,browser,devtools,emulator
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Framework :: FastAPI
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: fastapi>=0.115.0
25
+ Requires-Dist: uvicorn>=0.30.0
26
+ Requires-Dist: boto3>=1.35.0
27
+ Requires-Dist: click>=8.0
28
+ Requires-Dist: websockets>=12.0
29
+ Requires-Dist: python-multipart>=0.0.26
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
33
+ Requires-Dist: httpx>=0.27.0; extra == "dev"
34
+ Requires-Dist: moto[dynamodb,iam,lambda,s3,sqs]>=5.0; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ <p align="center">
38
+ <img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/stackport_logo.svg" alt="StackPort logo" width="150"/>
39
+ </p>
40
+
41
+ <h1 align="center">StackPort</h1>
42
+ <p align="center"><strong>A web console for local AWS emulators and real AWS accounts.</strong></p>
43
+ <p align="center">Browse, inspect, and manage resources across 35 AWS services, with dedicated views for 13 of them and guided lessons that teach AWS hands-on.</p>
44
+
45
+ <p align="center">
46
+ <a href="https://github.com/DaviReisVieira/stackport/actions/workflows/ci.yml"><img src="https://github.com/DaviReisVieira/stackport/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
47
+ <a href="https://pypi.org/project/stackport/"><img src="https://img.shields.io/pypi/v/stackport" alt="PyPI Version"></a>
48
+ <a href="https://hub.docker.com/r/davireis/stackport"><img src="https://img.shields.io/docker/pulls/davireis/stackport" alt="Docker Pulls"></a>
49
+ <a href="https://hub.docker.com/r/davireis/stackport"><img src="https://img.shields.io/docker/image-size/davireis/stackport/latest" alt="Docker Image Size"></a>
50
+ <a href="https://github.com/DaviReisVieira/stackport/blob/main/LICENSE"><img src="https://img.shields.io/github/license/DaviReisVieira/stackport" alt="License"></a>
51
+ <a href="https://pypi.org/project/stackport/"><img src="https://img.shields.io/pypi/pyversions/stackport" alt="Python versions"></a>
52
+ <a href="https://github.com/DaviReisVieira/stackport/stargazers"><img src="https://img.shields.io/github/stars/DaviReisVieira/stackport" alt="GitHub stars"></a>
53
+ </p>
54
+
55
+ <p align="center">
56
+ <img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/demo.gif" alt="StackPort demo: dashboard, S3 browser, and a guided lesson" width="900"/>
57
+ </p>
58
+
59
+ ## Why StackPort
60
+
61
+ Local emulators give you AWS on your laptop, but no console to look at it with. StackPort is that console: open source, runs locally with one command, and needs no AWS account. It talks to any AWS-compatible endpoint, and it can point at a real AWS account too, with a single setting to make it read-only.
62
+
63
+ ## Features
64
+
65
+ - **35 AWS services** discovered and counted on a live dashboard (WebSocket updates, pinned favorites, light and dark themes)
66
+ - **13 dedicated service views**: S3, DynamoDB, Lambda, SQS, SNS, IAM, EC2, RDS, CloudWatch Logs, CloudWatch metrics and alarms, Secrets Manager, KMS, and Step Functions. Every other service gets a searchable resource table
67
+ - **Write operations** in 9 of those views, from S3 uploads and DynamoDB item edits to SQS messages, Lambda invokes, EC2 start/stop, and Step Functions executions
68
+ - **Guided lessons** that run inside the console and check your real resource state as you go
69
+ - **Real AWS and multiple endpoints**, each with its own auth (default chain, AWS profile with SSO/AssumeRole, or static keys)
70
+ - **Read-only mode** with `STACKPORT_ALLOW_WRITES=false`
71
+ - **Tags** viewed and edited across 24 resource types
72
+ - **Export** resource lists to JSON or CSV, and a **CLI** for `status`, `list`, `describe`, and `export`
73
+ - **Keyboard shortcuts** for navigation (press `?` to see them)
74
+ - Single Docker image or `pip install`. Works with [MiniStack](https://github.com/ministackorg/ministack), [Floci](https://github.com/floci-io/floci), [LocalStack](https://github.com/localstack/localstack), [Moto](https://github.com/getmoto/moto), [AWS Emulator](https://github.com/aws/aws-emulator), or any AWS-compatible endpoint
75
+
76
+ ## Screenshots
77
+
78
+ <table>
79
+ <tr>
80
+ <td width="50%"><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dashboard.png" alt="Dashboard in dark mode with service counts"/><br/><sub><b>Dashboard</b>: every service with live resource counts</sub></td>
81
+ <td width="50%"><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dashboard-light.png" alt="Dashboard in light mode"/><br/><sub><b>Light mode</b>: light, dark, or follow the system</sub></td>
82
+ </tr>
83
+ <tr>
84
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/s3.png" alt="S3 file browser"/><br/><sub><b>S3</b>: folders, upload, download, bucket settings</sub></td>
85
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/lambda.png" alt="Lambda function view"/><br/><sub><b>Lambda</b>: config, aliases, versions, invoke</sub></td>
86
+ </tr>
87
+ <tr>
88
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dynamodb.png" alt="DynamoDB items view"/><br/><sub><b>DynamoDB</b>: scan, query, and edit items</sub></td>
89
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/stepfunctions.png" alt="Step Functions state machine graph"/><br/><sub><b>Step Functions</b>: state machine graph and execution timeline</sub></td>
90
+ </tr>
91
+ <tr>
92
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/sqs.png" alt="SQS queue view"/><br/><sub><b>SQS</b>: send, receive, purge, dead-letter queues</sub></td>
93
+ <td><img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/kms.png" alt="KMS key view"/><br/><sub><b>KMS</b>: keys, policies, grants, aliases</sub></td>
94
+ </tr>
95
+ </table>
96
+
97
+ ## Quick Start
98
+
99
+ ### With a local emulator
100
+
101
+ Start whichever emulator you use, then point StackPort at it:
102
+
103
+ ```bash
104
+ # Start an emulator on :4566 (pick one)
105
+ docker run -d -p 4566:4566 ministackorg/ministack # MiniStack
106
+ docker run -d -p 4566:4566 floci/floci # Floci
107
+
108
+ # Start StackPort
109
+ pip install stackport
110
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
111
+ # Open http://localhost:8080
112
+ ```
113
+
114
+ ### Docker Compose
115
+
116
+ Each example runs the emulator, StackPort, and a one-shot `seed` container that creates a few resources (S3, SQS, SNS, DynamoDB, Secrets Manager, IAM, Logs, Step Functions) so the dashboard has something to show on first load. They all use the same seed. Swap in LocalStack, Moto, or any AWS-compatible endpoint by replacing the emulator service and updating `AWS_ENDPOINT_URL`.
117
+
118
+ **MiniStack + StackPort**: [`examples/docker-compose.yml`](examples/docker-compose.yml)
119
+
120
+ ```bash
121
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.yml
122
+ docker compose up -d
123
+ # Open http://localhost:8080
124
+ # If the dashboard is empty: docker compose logs seed
125
+ ```
126
+
127
+ [MiniStack](https://github.com/ministackorg/ministack) derives the URLs it returns (SQS queue URLs, pre-signed URLs) from the request `Host`, so they resolve from other containers and from the host without extra configuration.
128
+
129
+ **Floci + StackPort**: [`examples/docker-compose.floci.yml`](examples/docker-compose.floci.yml)
130
+
131
+ ```bash
132
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.floci.yml
133
+ docker compose -f docker-compose.floci.yml up -d
134
+ # Open http://localhost:8080
135
+ # If the dashboard is empty: docker compose -f docker-compose.floci.yml logs seed
136
+ ```
137
+
138
+ [Floci](https://github.com/floci-io/floci) takes the hostname for the URLs it returns from `FLOCI_HOSTNAME`, which the example sets to `floci` so they resolve from other containers. From the host, reach the same resources through `http://localhost:4566`.
139
+
140
+ **AWS Emulator + StackPort**: [`examples/docker-compose.aws-emulator.yml`](examples/docker-compose.aws-emulator.yml)
141
+
142
+ ```bash
143
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.aws-emulator.yml
144
+ docker compose -f docker-compose.aws-emulator.yml up -d
145
+ # Open http://localhost:8080
146
+ # If the dashboard is empty: docker compose -f docker-compose.aws-emulator.yml logs seed
147
+ ```
148
+
149
+ [AWS Emulator](https://github.com/aws/aws-emulator) serves HTTPS with its own certificate and, by default, only accepts requests signed with keys it creates, both new on every start. StackPort reads them from `~/.aws/emulator/<port>/`, so it keeps working after a restart. There is no prebuilt image, so the first `up` builds one from the Dockerfile in [AWS's guide](https://docs.aws.amazon.com/emulator/latest/userguide/getting-started-docker.html), and the emulator keeps everything in memory.
150
+
151
+ ### Docker (standalone)
152
+
153
+ ```bash
154
+ docker run -p 127.0.0.1:8080:8080 -e AWS_ENDPOINT_URL=http://host.docker.internal:4566 davireis/stackport
155
+ ```
156
+
157
+ ### Other emulators
158
+
159
+ StackPort works with any AWS-compatible endpoint. Set `AWS_ENDPOINT_URL`:
160
+
161
+ ```bash
162
+ # LocalStack
163
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
164
+
165
+ # Moto
166
+ AWS_ENDPOINT_URL=http://localhost:5000 stackport
167
+
168
+ # AWS Emulator, started as in AWS's guide (StackPort reads its keys and certificate from ~/.aws/emulator)
169
+ AWS_ENDPOINT_URL=https://127.0.0.1:9297 stackport
170
+
171
+ # MinIO (S3 only)
172
+ AWS_ENDPOINT_URL=http://localhost:9000 stackport
173
+
174
+ # Any custom endpoint
175
+ AWS_ENDPOINT_URL=http://my-emulator:4566 stackport
176
+ ```
177
+
178
+ ## Real AWS and multiple endpoints
179
+
180
+ ### With real AWS
181
+
182
+ Leave `AWS_ENDPOINT_URL` unset and StackPort uses the standard AWS credential chain:
183
+
184
+ ```bash
185
+ # Using an AWS profile
186
+ AWS_PROFILE=my-profile stackport
187
+
188
+ # Using explicit credentials
189
+ AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-west-2 stackport
190
+
191
+ # Read-only: block every write from the UI and API
192
+ STACKPORT_ALLOW_WRITES=false AWS_PROFILE=my-profile stackport
193
+ ```
194
+
195
+ When connected to real AWS, StackPort shows a warning banner on every page. Writes stay enabled unless you set `STACKPORT_ALLOW_WRITES=false`, so use that whenever you only want to look. In read-only mode a lock appears in the top bar, and the only POST calls still allowed are the ones that read: DynamoDB queries, CloudWatch metric queries, and Lambda invokes (which run your function, so keep that in mind on a live account).
196
+
197
+ ### Multiple endpoints
198
+
199
+ Switch between endpoints from the UI. Configure named endpoints with `STACKPORT_ENDPOINTS`, or add them later from Settings:
200
+
201
+ ```bash
202
+ # A local emulator and a real AWS account (empty URL = real AWS)
203
+ STACKPORT_ENDPOINTS="local=http://localhost:4566,nprod=" \
204
+ AWS_PROFILE=nprod AWS_REGION=us-west-1 stackport
205
+ ```
206
+
207
+ **Docker Compose (local + real AWS):**
208
+
209
+ ```bash
210
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.multi-endpoint.yml
211
+ docker compose -f docker-compose.multi-endpoint.yml up -d
212
+ # Open http://localhost:8080
213
+ ```
214
+
215
+ See [`examples/docker-compose.multi-endpoint.yml`](examples/docker-compose.multi-endpoint.yml) for a full example with MiniStack + real AWS via profile.
216
+
217
+ The endpoint menu sits in the top navigation bar. Each endpoint is health-checked independently, and all API requests, caches, and WebSocket subscriptions are scoped to the active endpoint.
218
+
219
+ ### Per-endpoint authentication
220
+
221
+ Each endpoint can use its own AWS authentication method, configured from the Settings page:
222
+
223
+ | Auth Type | Description | Use Case |
224
+ |-----------|-------------|----------|
225
+ | **Default** | Uses AWS Emulator's own keys for an AWS Emulator endpoint, otherwise `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` env vars or instance role | Local emulators, EC2/ECS deployments |
226
+ | **AWS Profile** | Uses a named profile from `~/.aws/config` | SSO, AssumeRole, multiple accounts |
227
+ | **Static Credentials** | Per-endpoint access key and secret | Service accounts, cross-account access |
228
+
229
+ **Profile auth** supports SSO, AssumeRole, and credential_process (anything `boto3.Session(profile_name=...)` handles). If your SSO token expires, StackPort returns a 401 with instructions to run `aws sso login --profile <name>`.
230
+
231
+ **Docker users:** mount your AWS config to use profiles inside the container:
232
+
233
+ ```yaml
234
+ services:
235
+ stackport:
236
+ image: davireis/stackport
237
+ volumes:
238
+ - ~/.aws:/root/.aws
239
+ ```
240
+
241
+ **HTTPS endpoints** can also have their own certificate settings: a CA bundle to trust (a PEM file on the machine that runs StackPort), or certificate checks turned off. They are set per endpoint because `AWS_CA_BUNDLE` replaces the system certificates, so setting it for the whole process would break a real AWS endpoint configured next to an emulator. AWS Emulator needs neither when StackPort reaches it on 127.0.0.1 (on the same machine, or sharing its network as in the Compose example): StackPort trusts the certificate the emulator wrote to `~/.aws/emulator/<port>/` and, with the Default auth type, signs with the keys it wrote there.
242
+
243
+ You can test a connection before saving it with the "Test Connection" button in the add/edit endpoint dialog.
244
+
245
+ ## Service views
246
+
247
+ ### Dedicated views (13 services)
248
+
249
+ | Service | Browse | Write operations |
250
+ |---------|--------|------------------|
251
+ | **S3** | Buckets, objects, folder navigation, search | Create buckets and folders, upload, download, delete, batch delete; edit versioning, lifecycle, notifications, CORS, tags |
252
+ | **DynamoDB** | Tables, schema, items, scan and query | Create tables, add, edit and delete items, batch write |
253
+ | **Lambda** | Functions, config, aliases, versions, event sources | Invoke with a JSON payload, edit configuration, download code |
254
+ | **SQS** | Queues, messages, attributes | Create and delete queues, send (single or batch), receive, delete messages, purge, edit attributes and redrive policy |
255
+ | **SNS** | Topics, subscriptions | Create and delete topics, subscribe, unsubscribe, publish |
256
+ | **EC2** | Instances, Auto Scaling groups, VPCs and subnets, security group rules, key pairs | Start, stop, reboot, terminate instances |
257
+ | **CloudWatch Logs** | Log groups, streams, events with time and pattern filters, live tail | Create and delete log groups, delete streams, set retention |
258
+ | **Secrets Manager** | Secrets with value reveal, rotation status | Create, update value and metadata, delete, restore |
259
+ | **Step Functions** | State machines with an ASL graph, executions, execution timeline | Start and stop executions |
260
+ | **IAM** | Users, roles, groups, policies, trust policies | Read-only |
261
+ | **RDS** | Instances, clusters, snapshots, parameter groups | Read-only |
262
+ | **CloudWatch** | Dashboards, alarms, metric charts | Read-only |
263
+ | **KMS** | Keys, key policies, grants, aliases | Read-only |
264
+
265
+ ### Generic resource browser (22 services)
266
+
267
+ Every other service uses a searchable resource table with a JSON detail view, tag editing where supported, pagination, and export to JSON or CSV.
268
+
269
+ ## Guided lessons
270
+
271
+ Learn AWS hands-on without an AWS account or a bill. Lessons run inside StackPort against your own emulator: a panel walks you through each step while hotspots point at the actual controls, and StackPort checks the live resource state, so a step only turns green when the thing really exists.
272
+
273
+ <p align="center">
274
+ <img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/learn.png" alt="A guided lesson running inside the StackPort console" width="900"/>
275
+ </p>
276
+
277
+ Open **Learn** in the sidebar (or press `g l`) and start a lesson. Every step gives you two ways through it:
278
+
279
+ - **Do it here**: the popover points at the control to use, with the exact values to type, copyable.
280
+ - **With the CLI**: the command, already filled in with your endpoint and your resource names, plus an explanation of what each flag does.
281
+
282
+ Either way, verification is the same: StackPort calls the real API and reports what it found. Do the work in a terminal and the step turns green on its own within a few seconds, no clicking required. Nothing is a gate, either: any step can be skipped and re-checked later.
283
+
284
+ You pick the names. A lesson generates something like `stackport-learn-k3xz` and every command and field on screen uses it, so the commands can be copied and run without editing. Change it under "Names used in this lesson" and everything follows.
285
+
286
+ Lessons only run against a local emulator, since they create and delete resources. Progress is stored locally in `~/.stackport/learn_progress.json`. Set `STACKPORT_LEARN=false` to remove Learn entirely.
287
+
288
+ ## Tag management
289
+
290
+ Tags can be read on 24 resource types and edited on 23 of them (CloudFormation stacks are read-only):
291
+
292
+ S3 buckets, DynamoDB tables, Lambda functions, SQS queues, SNS topics, IAM users/roles/policies, EC2 instances, CloudWatch log groups, Secrets Manager secrets, RDS instances/clusters, KMS keys, ECR repositories, CloudFormation stacks, Step Functions state machines, Kinesis streams, SSM parameters, ELB load balancers, ElastiCache clusters, Cognito user pools, EMR clusters, API Gateway REST APIs
293
+
294
+ ## CLI
295
+
296
+ ```bash
297
+ # Start the web UI (same as running `stackport` with no arguments)
298
+ stackport serve --port 8080
299
+
300
+ # Show service availability and resource counts
301
+ stackport status
302
+ stackport status --output json
303
+
304
+ # List resources for a service
305
+ stackport list s3
306
+ stackport list dynamodb --output csv
307
+
308
+ # Get resource details
309
+ stackport describe s3 buckets my-bucket
310
+ stackport describe lambda functions my-func --output table
311
+
312
+ # Export all resources
313
+ stackport export lambda --format json
314
+ stackport export ec2 --format csv
315
+ ```
316
+
317
+ `status`, `list`, `describe`, and `export` accept `--endpoint URL` and `--region REGION`. Without them they use `AWS_ENDPOINT_URL` and `AWS_REGION`, or the default endpoint saved in Settings.
318
+
319
+ ## Keyboard shortcuts
320
+
321
+ Press `?` anywhere to see all shortcuts.
322
+
323
+ | Key | Action |
324
+ |-----|--------|
325
+ | `?` | Show shortcuts |
326
+ | `Alt+S` (`⌥S` on macOS) | Focus service search |
327
+ | `b` | Toggle sidebar |
328
+ | `t` | Toggle theme |
329
+ | `g d` / `g r` / `g l` | Go to Dashboard / Resources / Learn |
330
+ | `g s` / `g a` | Go to Settings / About |
331
+ | `r` / `v` | Dashboard: refresh / switch grid and list view |
332
+ | `j` / `k` | Next / previous row in a resource list |
333
+ | `Enter` | Open selected row |
334
+ | `Esc` | Close modal |
335
+
336
+ ## Configuration
337
+
338
+ | Variable | Default | Description |
339
+ |---|---|---|
340
+ | `AWS_ENDPOINT_URL` | *(unset)* | AWS endpoint. Unset = real AWS via credential chain |
341
+ | `AWS_REGION` | `us-east-1` | AWS region |
342
+ | `AWS_ACCESS_KEY_ID` | *(unset)* | AWS access key. Unset = use credential chain |
343
+ | `AWS_SECRET_ACCESS_KEY` | *(unset)* | AWS secret key. Unset = use credential chain |
344
+ | `AWS_PROFILE` | *(unset)* | AWS named profile from `~/.aws/config` |
345
+ | `STACKPORT_PORT` | `8080` | StackPort server port |
346
+ | `STACKPORT_HOST` | `127.0.0.1` | Interface StackPort listens on (`0.0.0.0` in the Docker image). StackPort has no login, so open it to the network only where that's fine |
347
+ | `STACKPORT_ALLOW_WRITES` | `true` | Allow write operations. `false` makes StackPort read-only |
348
+ | `STACKPORT_S3_MAX_UPLOAD_MB` | `100` | Max S3 upload size per object (MiB) |
349
+ | `STACKPORT_LEARN` | `true` | Guided lessons. `false` removes the Learn routes and UI |
350
+ | `STACKPORT_SERVICES` | *(35 services)* | Comma-separated list of services to probe |
351
+ | `STACKPORT_PROBE_TIMEOUT` | `5` | Seconds to wait when connecting to a local emulator. Calls to local emulators aren't retried |
352
+ | `STACKPORT_CACHE_TTL` | `5` | Seconds to cache service stats |
353
+ | `STACKPORT_PROBE_WORKERS` | `10` | Max concurrent workers for service probing |
354
+ | `STACKPORT_ENDPOINTS` | *(unset)* | Multiple endpoints: `local=http://localhost:4566,staging=http://...` |
355
+ | `STACKPORT_DATA_DIR` | `~/.stackport` | Directory for persistent config (endpoints.json, learn_progress.json) |
356
+ | `STACKPORT_ALLOWED_HOSTS` | *(empty)* | Host names browsers may open StackPort through besides `localhost` and IP addresses (comma-separated, `*` for any). Needed behind a reverse proxy, a forwarded port, or a machine name |
357
+ | `STACKPORT_CORS_ORIGINS` | *(empty)* | Comma-separated origins allowed to call StackPort's API from another site. Empty means only StackPort's own pages |
358
+ | `STACKPORT_AWS_EMULATOR_DIR` | `~/.aws/emulator` | Where to look for the keys and certificate AWS Emulator writes for each port. Empty turns the lookup off |
359
+ | `LOG_LEVEL` | `INFO` | Python log level (`DEBUG` shows healthcheck logs) |
360
+
361
+ ## Supported services (35)
362
+
363
+ ACM, API Gateway, AppSync, Athena, CloudFormation, CloudFront, CloudWatch (metrics and alarms), CloudWatch Logs, Cognito (User Pools + Identity Pools), DynamoDB, EC2, ECR, ECS, EFS, ElastiCache, ELB, EMR, EventBridge, Firehose, Glue, IAM, Kinesis, KMS, Lambda, RDS, Route 53, S3, Secrets Manager, SES, SNS, SQS, SSM, Step Functions, WAFv2
364
+
365
+ ## Development
366
+
367
+ ```bash
368
+ git clone https://github.com/DaviReisVieira/stackport.git
369
+ cd stackport
370
+
371
+ # Backend (with test dependencies)
372
+ pip install -e ".[dev]"
373
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
374
+
375
+ # Frontend dev (with hot reload, proxies to :8080)
376
+ cd ui && npm install && npm run dev
377
+
378
+ # Build frontend for production
379
+ cd ui && npm run build
380
+
381
+ # Run tests
382
+ python -m pytest -x --tb=short # backend
383
+ cd ui && npx vitest run # frontend
384
+
385
+ # Typecheck & lint
386
+ cd ui && npx tsc -b
387
+ cd ui && npx eslint .
388
+ ```
389
+
390
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full details.
391
+
392
+ ## Architecture
393
+
394
+ ```text
395
+ backend/
396
+ main.py FastAPI app, CORS, read-only middleware, SPA mount
397
+ cli.py serve, status, list, describe, export
398
+ config.py All settings from environment variables
399
+ aws_client.py Cached boto3 client factory
400
+ cache.py Thread-safe TTL cache
401
+ websocket.py Live dashboard probes and log tailing
402
+ schemas/ Pydantic request models, one module per service
403
+ learn/ Lesson content (trails/*.json), hotspot ids, verification checks
404
+ routes/
405
+ stats.py Service registry and concurrent probing
406
+ resources.py Generic list/detail for all services
407
+ endpoints.py Endpoint CRUD, health checks, profile listing
408
+ tags.py Unified tag management
409
+ learn.py Lessons, progress, verification
410
+ s3.py, dynamodb.py, lambda_svc.py, sqs.py, sns.py, iam.py, ec2.py,
411
+ rds.py, logs.py, monitoring.py, secretsmanager.py, kms.py,
412
+ stepfunctions.py One module per dedicated view
413
+
414
+ ui/src/
415
+ pages/ Dashboard, ResourceBrowser, Learn, Settings, About
416
+ components/
417
+ cloudscape/ AppLayout shell, service views, Learn panel (Cloudscape Design System)
418
+ contexts/ Endpoint and Learn state
419
+ hooks/ useFetch, useWebSocket, useKeyboardShortcuts, ...
420
+ lib/ API client, types, service icons, export, utils
421
+ ```
422
+
423
+ ## Origin
424
+
425
+ StackPort started as a web UI pull request to [MiniStack](https://github.com/ministackorg/ministack) ([ministack#116](https://github.com/ministackorg/ministack/pull/116)). The MiniStack maintainers suggested it would be more useful as a standalone tool that talks to any emulator over the standard AWS API, and that is what it became. Thanks to [@Nahuel990](https://github.com/Nahuel990) and [@McDoit](https://github.com/McDoit) for pushing it in that direction.
426
+
427
+ ## Contributors
428
+
429
+ Contributions of every size are welcome. [CONTRIBUTING.md](CONTRIBUTING.md) has the setup and a few good places to start.
430
+
431
+ <a href="https://github.com/DaviReisVieira/stackport/graphs/contributors">
432
+ <img src="https://contrib.rocks/image?repo=DaviReisVieira/stackport" alt="Contributors" />
433
+ </a>
434
+
435
+ ## Support the project
436
+
437
+ If StackPort saves you time, a [star on GitHub](https://github.com/DaviReisVieira/stackport/stargazers) helps other people find it.
438
+
439
+ More guides live at [stackport.cloud](https://stackport.cloud): [introduction](https://stackport.cloud/docs/introduction/), [quick start](https://stackport.cloud/docs/quickstart/), [environment variables](https://stackport.cloud/docs/configuration/environment-variables/), and [CLI commands](https://stackport.cloud/docs/cli/commands/). Questions and bug reports go to [GitHub Issues](https://github.com/DaviReisVieira/stackport/issues).
440
+
441
+ ## License
442
+
443
+ [MIT](LICENSE)