stackport 0.2.0__tar.gz → 0.2.1__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 (100) hide show
  1. stackport-0.2.1/PKG-INFO +325 -0
  2. stackport-0.2.1/README.md +290 -0
  3. stackport-0.2.1/backend/aws_client.py +42 -0
  4. {stackport-0.2.0 → stackport-0.2.1}/backend/config.py +30 -9
  5. {stackport-0.2.0 → stackport-0.2.1}/backend/main.py +40 -3
  6. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/common.py +6 -5
  7. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/dynamodb.py +13 -11
  8. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/ec2.py +20 -19
  9. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/endpoints.py +9 -3
  10. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/iam.py +18 -17
  11. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/lambda_svc.py +16 -15
  12. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/logs.py +10 -6
  13. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/s3.py +57 -43
  14. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/secretsmanager.py +6 -5
  15. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/sqs.py +14 -12
  16. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/stats.py +9 -2
  17. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/tags.py +11 -10
  18. stackport-0.2.1/backend/websocket.py +122 -0
  19. {stackport-0.2.0 → stackport-0.2.1}/pyproject.toml +1 -1
  20. stackport-0.2.1/stackport.egg-info/PKG-INFO +325 -0
  21. {stackport-0.2.0 → stackport-0.2.1}/stackport.egg-info/SOURCES.txt +6 -4
  22. stackport-0.2.1/tests/test_config.py +163 -0
  23. {stackport-0.2.0 → stackport-0.2.1}/tests/test_endpoints.py +18 -0
  24. stackport-0.2.1/tests/test_multi_endpoint.py +330 -0
  25. stackport-0.2.1/tests/test_readonly_middleware.py +105 -0
  26. {stackport-0.2.0 → stackport-0.2.1}/tests/test_routes.py +8 -0
  27. {stackport-0.2.0 → stackport-0.2.1}/tests/test_s3_routes.py +49 -0
  28. {stackport-0.2.0 → stackport-0.2.1}/tests/test_websocket.py +1 -1
  29. stackport-0.2.1/ui/dist/assets/index-BNpVm9Z9.js +568 -0
  30. stackport-0.2.1/ui/dist/assets/index-CgkBNKzX.css +1 -0
  31. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/index.html +2 -2
  32. stackport-0.2.0/PKG-INFO +0 -165
  33. stackport-0.2.0/README.md +0 -130
  34. stackport-0.2.0/backend/aws_client.py +0 -31
  35. stackport-0.2.0/backend/websocket.py +0 -110
  36. stackport-0.2.0/stackport.egg-info/PKG-INFO +0 -165
  37. stackport-0.2.0/tests/test_config.py +0 -71
  38. stackport-0.2.0/ui/dist/assets/index-BauDt01Y.css +0 -1
  39. stackport-0.2.0/ui/dist/assets/index-CMbP0j4Q.js +0 -563
  40. {stackport-0.2.0 → stackport-0.2.1}/LICENSE +0 -0
  41. {stackport-0.2.0 → stackport-0.2.1}/MANIFEST.in +0 -0
  42. {stackport-0.2.0 → stackport-0.2.1}/backend/__init__.py +0 -0
  43. {stackport-0.2.0 → stackport-0.2.1}/backend/cache.py +0 -0
  44. {stackport-0.2.0 → stackport-0.2.1}/backend/cli.py +0 -0
  45. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/__init__.py +0 -0
  46. {stackport-0.2.0 → stackport-0.2.1}/backend/routes/resources.py +0 -0
  47. {stackport-0.2.0 → stackport-0.2.1}/setup.cfg +0 -0
  48. {stackport-0.2.0 → stackport-0.2.1}/stackport.egg-info/dependency_links.txt +0 -0
  49. {stackport-0.2.0 → stackport-0.2.1}/stackport.egg-info/entry_points.txt +0 -0
  50. {stackport-0.2.0 → stackport-0.2.1}/stackport.egg-info/requires.txt +0 -0
  51. {stackport-0.2.0 → stackport-0.2.1}/stackport.egg-info/top_level.txt +0 -0
  52. {stackport-0.2.0 → stackport-0.2.1}/tests/test_cache.py +0 -0
  53. {stackport-0.2.0 → stackport-0.2.1}/tests/test_cli.py +0 -0
  54. {stackport-0.2.0 → stackport-0.2.1}/tests/test_client.py +0 -0
  55. {stackport-0.2.0 → stackport-0.2.1}/tests/test_dynamodb_routes.py +0 -0
  56. {stackport-0.2.0 → stackport-0.2.1}/tests/test_ec2_routes.py +0 -0
  57. {stackport-0.2.0 → stackport-0.2.1}/tests/test_iam_routes.py +0 -0
  58. {stackport-0.2.0 → stackport-0.2.1}/tests/test_lambda_routes.py +0 -0
  59. {stackport-0.2.0 → stackport-0.2.1}/tests/test_logs_routes.py +0 -0
  60. {stackport-0.2.0 → stackport-0.2.1}/tests/test_registries.py +0 -0
  61. {stackport-0.2.0 → stackport-0.2.1}/tests/test_s3_upload_limit_env.py +0 -0
  62. {stackport-0.2.0 → stackport-0.2.1}/tests/test_secretsmanager_routes.py +0 -0
  63. {stackport-0.2.0 → stackport-0.2.1}/tests/test_sqs_routes.py +0 -0
  64. {stackport-0.2.0 → stackport-0.2.1}/tests/test_tags_routes.py +0 -0
  65. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/acm.svg +0 -0
  66. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/apigateway.svg +0 -0
  67. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/appsync.svg +0 -0
  68. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/athena.svg +0 -0
  69. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/cloudformation.svg +0 -0
  70. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/cloudfront.svg +0 -0
  71. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/cognito-idp.svg +0 -0
  72. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/dynamodb.svg +0 -0
  73. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/ec2.svg +0 -0
  74. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/ecr.svg +0 -0
  75. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/ecs.svg +0 -0
  76. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/elasticache.svg +0 -0
  77. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/elasticfilesystem.svg +0 -0
  78. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/elasticloadbalancing.svg +0 -0
  79. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/elasticmapreduce.svg +0 -0
  80. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/events.svg +0 -0
  81. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/firehose.svg +0 -0
  82. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/glue.svg +0 -0
  83. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/iam.svg +0 -0
  84. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/kinesis.svg +0 -0
  85. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/kms.svg +0 -0
  86. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/lambda.svg +0 -0
  87. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/logs.svg +0 -0
  88. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/monitoring.svg +0 -0
  89. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/rds.svg +0 -0
  90. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/route53.svg +0 -0
  91. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/s3.svg +0 -0
  92. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/secretsmanager.svg +0 -0
  93. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/ses.svg +0 -0
  94. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/sns.svg +0 -0
  95. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/sqs.svg +0 -0
  96. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/ssm.svg +0 -0
  97. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/stepfunctions.svg +0 -0
  98. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/aws-icons/wafv2.svg +0 -0
  99. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/favicon.png +0 -0
  100. {stackport-0.2.0 → stackport-0.2.1}/ui/dist/favicon.svg +0 -0
@@ -0,0 +1,325 @@
1
+ Metadata-Version: 2.4
2
+ Name: stackport
3
+ Version: 0.2.1
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,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: httpx>=0.27.0; extra == "dev"
33
+ Requires-Dist: moto[dynamodb,iam,lambda,s3,sqs]>=5.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ <p align="center">
37
+ <img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/stackport_logo.svg" alt="StackPort — Universal AWS Resource Browser" width="150"/>
38
+ </p>
39
+
40
+ <h1 align="center">StackPort</h1>
41
+ <p align="center"><strong>Universal AWS resource browser for local emulators and real AWS accounts.</strong></p>
42
+ <p align="center">Browse, inspect, and manage resources across 35 AWS services with dedicated UIs for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager.</p>
43
+
44
+ <p align="center">
45
+ <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>
46
+ <a href="https://pypi.org/project/stackport/"><img src="https://img.shields.io/pypi/v/stackport" alt="PyPI Version"></a>
47
+ <a href="https://hub.docker.com/r/davireis/stackport"><img src="https://img.shields.io/docker/pulls/davireis/stackport" alt="Docker Pulls"></a>
48
+ <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>
49
+ <a href="https://github.com/DaviReisVieira/stackport/blob/master/LICENSE"><img src="https://img.shields.io/github/license/DaviReisVieira/stackport" alt="License"></a>
50
+ <img src="https://img.shields.io/badge/python-3.12-slim" alt="Python">
51
+ <a href="https://github.com/DaviReisVieira/stackport/stargazers"><img src="https://img.shields.io/github/stars/DaviReisVieira/stackport" alt="GitHub stars"></a>
52
+ </p>
53
+
54
+ ## Screenshots
55
+
56
+ **Dashboard** — Service overview with resource counts and health status
57
+ ![StackPort Dashboard](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dashboard.jpeg)
58
+
59
+ **DynamoDB Browser** — Query and scan tables with schema visualization
60
+ ![DynamoDB Resources](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dynamo.jpeg)
61
+
62
+ **S3 Browser** — File browser with upload, download, folder navigation, and tagging
63
+ ![S3 Browser](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/s3.jpeg)
64
+
65
+ ## Features
66
+
67
+ - Browse and inspect resources across **35 AWS services**
68
+ - **8 dedicated service UIs** for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager
69
+ - **Write operations** — upload/delete S3 objects, query DynamoDB, invoke Lambda, send/receive SQS messages
70
+ - **Real AWS support** — connect to real AWS accounts with read-only mode by default
71
+ - **Tag management** — unified tagging across 21 resource types
72
+ - **CLI** — `stackport status`, `list`, `describe`, `export` with JSON/CSV/table output
73
+ - **Real-time dashboard** with WebSocket-powered live updates
74
+ - **Keyboard shortcuts** — 16 shortcuts for fast navigation (press `?` to view)
75
+ - Single Docker image, works with MiniStack, LocalStack, Moto, or any AWS-compatible endpoint
76
+
77
+ ## Quick Start
78
+
79
+ ### With a local emulator (recommended)
80
+
81
+ ```bash
82
+ # Start MiniStack (or LocalStack, Moto, etc.)
83
+ pip install ministack && ministack
84
+
85
+ # Start StackPort
86
+ pip install stackport
87
+ stackport
88
+ # Open http://localhost:8080
89
+ ```
90
+
91
+ ### With real AWS
92
+
93
+ ```bash
94
+ # Using AWS profile (read-only by default)
95
+ AWS_PROFILE=my-profile stackport
96
+
97
+ # Using explicit credentials
98
+ AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-west-2 stackport
99
+
100
+ # Disable write operations (read-only mode)
101
+ STACKPORT_ALLOW_WRITES=false AWS_PROFILE=my-profile stackport
102
+ ```
103
+
104
+ When connected to real AWS, StackPort shows a warning banner and operates in read-only mode unless writes are explicitly enabled.
105
+
106
+ ### Docker Compose (MiniStack + StackPort)
107
+
108
+ This example uses [MiniStack](https://github.com/Nahuel990/ministack) as the emulator, but you can swap it for LocalStack, Moto, or any AWS-compatible endpoint — just update `AWS_ENDPOINT_URL`.
109
+
110
+ ```bash
111
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.yml
112
+ docker compose up -d
113
+ # Open http://localhost:8080
114
+ ```
115
+
116
+ ### Docker (standalone)
117
+
118
+ ```bash
119
+ docker run -p 8080:8080 -e AWS_ENDPOINT_URL=http://host.docker.internal:4566 davireis/stackport
120
+ ```
121
+
122
+ ### Other emulators
123
+
124
+ StackPort works with any AWS-compatible endpoint — just set `AWS_ENDPOINT_URL`:
125
+
126
+ ```bash
127
+ # LocalStack
128
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
129
+
130
+ # Moto
131
+ AWS_ENDPOINT_URL=http://localhost:5000 stackport
132
+
133
+ # MinIO (S3 only)
134
+ AWS_ENDPOINT_URL=http://localhost:9000 stackport
135
+
136
+ # Any custom endpoint
137
+ AWS_ENDPOINT_URL=http://my-emulator:4566 stackport
138
+ ```
139
+
140
+ ### Multiple endpoints
141
+
142
+ Switch between multiple AWS endpoints from the UI. Configure named endpoints with `STACKPORT_ENDPOINTS`:
143
+
144
+ ```bash
145
+ # Connect to a local emulator and a real AWS account (empty URL = real AWS)
146
+ STACKPORT_ENDPOINTS="local=http://localhost:4566,nprod=" \
147
+ AWS_PROFILE=nprod AWS_REGION=us-west-1 stackport
148
+ ```
149
+
150
+ **Docker Compose (local + real AWS):**
151
+
152
+ ```bash
153
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.multi-endpoint.yml
154
+ docker compose -f docker-compose.multi-endpoint.yml up -d
155
+ # Open http://localhost:8080
156
+ ```
157
+
158
+ See [`examples/docker-compose.multi-endpoint.yml`](examples/docker-compose.multi-endpoint.yml) for a full example with MiniStack + real AWS via profile.
159
+
160
+ The endpoint selector appears in the sidebar when more than one endpoint is configured. Each endpoint is health-checked independently, and all API requests, caches, and WebSocket subscriptions are scoped to the active endpoint.
161
+
162
+ ## Service Browsers
163
+
164
+ ### Dedicated UIs (8 services)
165
+
166
+ | Service | Browse | Write Operations |
167
+ |---------|--------|-----------------|
168
+ | **S3** | Buckets, objects, folder navigation, search | Upload, download, delete, batch delete, create folders |
169
+ | **DynamoDB** | Tables, schema, items | Query by partition/sort key, scan |
170
+ | **Lambda** | Functions, config, aliases, versions, event sources | Invoke with JSON payload, download code |
171
+ | **SQS** | Queues, messages, attributes | Send, receive, delete messages, purge queue |
172
+ | **IAM** | Users, roles, groups, policies, trust policies | Read-only |
173
+ | **EC2** | Instances, VPCs, subnets, security groups, volumes | Read-only |
174
+ | **CloudWatch Logs** | Log groups, streams, events with time filtering | Read-only |
175
+ | **Secrets Manager** | Secrets with value reveal, rotation status | Read-only |
176
+
177
+ ### Generic Resource Browser (27 services)
178
+
179
+ All other services use a searchable resource table with JSON detail view, pagination, and export (JSON/CSV).
180
+
181
+ ## Tag Management
182
+
183
+ Unified tag read/write across 21 resource types:
184
+
185
+ S3 buckets, DynamoDB tables, Lambda functions, SQS queues, IAM users/roles/policies, EC2 instances/security groups/volumes, CloudWatch log groups, Secrets Manager secrets, RDS instances/clusters, SNS topics, KMS keys, ECR repositories, CloudFormation stacks, Step Functions state machines, Kinesis streams, SSM parameters, ELB load balancers, ElastiCache clusters
186
+
187
+ ## CLI
188
+
189
+ ```bash
190
+ # Show service availability and resource counts
191
+ stackport status
192
+ stackport status --output json
193
+
194
+ # List resources for a service
195
+ stackport list s3
196
+ stackport list dynamodb --output csv
197
+
198
+ # Get resource details
199
+ stackport describe s3 buckets my-bucket
200
+ stackport describe lambda functions my-func --output json
201
+
202
+ # Export all resources
203
+ stackport export lambda --format json
204
+ stackport export ec2 --format csv
205
+ ```
206
+
207
+ All CLI commands accept `--endpoint URL` and `--region REGION` overrides.
208
+
209
+ ## Keyboard Shortcuts
210
+
211
+ Press `?` anywhere to see all shortcuts.
212
+
213
+ | Key | Action |
214
+ |-----|--------|
215
+ | `?` | Show shortcuts modal |
216
+ | `b` | Toggle sidebar |
217
+ | `g d` | Go to Dashboard |
218
+ | `g r` | Go to Resources |
219
+ | `/` | Focus search |
220
+ | `j` / `k` | Navigate up/down in resource list |
221
+ | `[` / `]` | Previous/next service |
222
+ | `Enter` | Open selected resource |
223
+ | `r` | Refresh current view |
224
+ | `Esc` | Close panel / clear selection |
225
+
226
+ ## Configuration
227
+
228
+ | Variable | Default | Description |
229
+ |---|---|---|
230
+ | `AWS_ENDPOINT_URL` | *(unset)* | AWS endpoint. Unset = real AWS via credential chain |
231
+ | `AWS_REGION` | `us-east-1` | AWS region |
232
+ | `AWS_ACCESS_KEY_ID` | *(unset)* | AWS access key. Unset = use credential chain |
233
+ | `AWS_SECRET_ACCESS_KEY` | *(unset)* | AWS secret key. Unset = use credential chain |
234
+ | `AWS_PROFILE` | *(unset)* | AWS named profile from `~/.aws/credentials` |
235
+ | `STACKPORT_PORT` | `8080` | StackPort server port |
236
+ | `STACKPORT_ALLOW_WRITES` | `true` | Enable write operations (POST/PUT/DELETE) |
237
+ | `STACKPORT_S3_MAX_UPLOAD_MB` | `100` | Max S3 upload size per object (MiB) |
238
+ | `STACKPORT_SERVICES` | *(35 services)* | Comma-separated list of services to probe |
239
+ | `STACKPORT_PROBE_TIMEOUT` | `5` | Seconds before a service probe times out |
240
+ | `STACKPORT_CACHE_TTL` | `5` | Seconds to cache service stats |
241
+ | `STACKPORT_PROBE_WORKERS` | `10` | Max concurrent workers for service probing |
242
+ | `STACKPORT_ENDPOINTS` | *(unset)* | Multiple endpoints: `local=http://localhost:4566,staging=http://...` |
243
+ | `LOG_LEVEL` | `INFO` | Python log level (`DEBUG` shows healthcheck logs) |
244
+
245
+ ## Supported Services (35)
246
+
247
+ ACM, API Gateway, AppSync, Athena, CloudFormation, CloudFront, Cognito (IDP + Identity), DynamoDB, EC2, ECR, ECS, ElastiCache, EFS, ELB, EMR, EventBridge, Firehose, Glue, IAM, Kinesis, KMS, Lambda, CloudWatch Logs, CloudWatch Monitoring, RDS, Route 53, S3, Secrets Manager, SES, SNS, SQS, SSM, Step Functions, STS, WAFv2
248
+
249
+ ## Development
250
+
251
+ ```bash
252
+ git clone https://github.com/DaviReisVieira/stackport.git
253
+ cd stackport
254
+
255
+ # Backend
256
+ pip install -e .
257
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
258
+
259
+ # Frontend dev (with hot reload)
260
+ cd ui && npm install && npm run dev
261
+
262
+ # Build frontend for production
263
+ cd ui && npm run build
264
+
265
+ # Run tests
266
+ python -m pytest tests/ -x --tb=short # backend (262 tests)
267
+ cd ui && npx vitest run # frontend (163 tests)
268
+
269
+ # Typecheck & lint
270
+ cd ui && npx tsc -b
271
+ cd ui && npx eslint .
272
+ ```
273
+
274
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full details.
275
+
276
+ ## Architecture
277
+
278
+ ```
279
+ backend/
280
+ main.py FastAPI app, CORS, read-only middleware, SPA mount
281
+ config.py All settings from environment variables
282
+ aws_client.py Cached boto3 client factory
283
+ cache.py Thread-safe TTL cache
284
+ websocket.py Real-time probe loop for dashboard
285
+ routes/
286
+ stats.py Service discovery with concurrent probing
287
+ resources.py Generic list/detail for all services
288
+ tags.py Unified tag management (21 types)
289
+ s3.py S3 file browser with write ops
290
+ dynamodb.py DynamoDB query/scan
291
+ lambda_svc.py Lambda invoke/config/code
292
+ sqs.py SQS send/receive/purge
293
+ iam.py IAM users/roles/groups/policies
294
+ ec2.py EC2 instances/VPCs/security groups
295
+ logs.py CloudWatch log streams/events
296
+ secretsmanager.py Secret value retrieval
297
+
298
+ ui/src/
299
+ pages/ Dashboard, ResourceBrowser, About
300
+ components/
301
+ service-views/ S3Browser, DynamoDBBrowser, LambdaBrowser, ...
302
+ ui/ shadcn/ui components (Radix-based)
303
+ hooks/ useFetch, useWebSocket, useKeyboardShortcuts, ...
304
+ lib/ API client, types, service icons, utils
305
+ ```
306
+
307
+ ## Star History
308
+
309
+ <a href="https://star-history.com/#DaviReisVieira/stackport&Date">
310
+ <picture>
311
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date&theme=dark" />
312
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date" />
313
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date" width="100%" />
314
+ </picture>
315
+ </a>
316
+
317
+ ## Contributors
318
+
319
+ <a href="https://github.com/DaviReisVieira/stackport/graphs/contributors">
320
+ <img src="https://contrib.rocks/image?repo=DaviReisVieira/stackport" alt="Contributors" />
321
+ </a>
322
+
323
+ ## License
324
+
325
+ MIT
@@ -0,0 +1,290 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/stackport_logo.svg" alt="StackPort — Universal AWS Resource Browser" width="150"/>
3
+ </p>
4
+
5
+ <h1 align="center">StackPort</h1>
6
+ <p align="center"><strong>Universal AWS resource browser for local emulators and real AWS accounts.</strong></p>
7
+ <p align="center">Browse, inspect, and manage resources across 35 AWS services with dedicated UIs for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager.</p>
8
+
9
+ <p align="center">
10
+ <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>
11
+ <a href="https://pypi.org/project/stackport/"><img src="https://img.shields.io/pypi/v/stackport" alt="PyPI Version"></a>
12
+ <a href="https://hub.docker.com/r/davireis/stackport"><img src="https://img.shields.io/docker/pulls/davireis/stackport" alt="Docker Pulls"></a>
13
+ <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>
14
+ <a href="https://github.com/DaviReisVieira/stackport/blob/master/LICENSE"><img src="https://img.shields.io/github/license/DaviReisVieira/stackport" alt="License"></a>
15
+ <img src="https://img.shields.io/badge/python-3.12-slim" alt="Python">
16
+ <a href="https://github.com/DaviReisVieira/stackport/stargazers"><img src="https://img.shields.io/github/stars/DaviReisVieira/stackport" alt="GitHub stars"></a>
17
+ </p>
18
+
19
+ ## Screenshots
20
+
21
+ **Dashboard** — Service overview with resource counts and health status
22
+ ![StackPort Dashboard](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dashboard.jpeg)
23
+
24
+ **DynamoDB Browser** — Query and scan tables with schema visualization
25
+ ![DynamoDB Resources](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/dynamo.jpeg)
26
+
27
+ **S3 Browser** — File browser with upload, download, folder navigation, and tagging
28
+ ![S3 Browser](https://raw.githubusercontent.com/DaviReisVieira/stackport/main/docs/images/s3.jpeg)
29
+
30
+ ## Features
31
+
32
+ - Browse and inspect resources across **35 AWS services**
33
+ - **8 dedicated service UIs** for S3, DynamoDB, Lambda, SQS, IAM, EC2, CloudWatch Logs, and Secrets Manager
34
+ - **Write operations** — upload/delete S3 objects, query DynamoDB, invoke Lambda, send/receive SQS messages
35
+ - **Real AWS support** — connect to real AWS accounts with read-only mode by default
36
+ - **Tag management** — unified tagging across 21 resource types
37
+ - **CLI** — `stackport status`, `list`, `describe`, `export` with JSON/CSV/table output
38
+ - **Real-time dashboard** with WebSocket-powered live updates
39
+ - **Keyboard shortcuts** — 16 shortcuts for fast navigation (press `?` to view)
40
+ - Single Docker image, works with MiniStack, LocalStack, Moto, or any AWS-compatible endpoint
41
+
42
+ ## Quick Start
43
+
44
+ ### With a local emulator (recommended)
45
+
46
+ ```bash
47
+ # Start MiniStack (or LocalStack, Moto, etc.)
48
+ pip install ministack && ministack
49
+
50
+ # Start StackPort
51
+ pip install stackport
52
+ stackport
53
+ # Open http://localhost:8080
54
+ ```
55
+
56
+ ### With real AWS
57
+
58
+ ```bash
59
+ # Using AWS profile (read-only by default)
60
+ AWS_PROFILE=my-profile stackport
61
+
62
+ # Using explicit credentials
63
+ AWS_ACCESS_KEY_ID=AKIA... AWS_SECRET_ACCESS_KEY=... AWS_REGION=us-west-2 stackport
64
+
65
+ # Disable write operations (read-only mode)
66
+ STACKPORT_ALLOW_WRITES=false AWS_PROFILE=my-profile stackport
67
+ ```
68
+
69
+ When connected to real AWS, StackPort shows a warning banner and operates in read-only mode unless writes are explicitly enabled.
70
+
71
+ ### Docker Compose (MiniStack + StackPort)
72
+
73
+ This example uses [MiniStack](https://github.com/Nahuel990/ministack) as the emulator, but you can swap it for LocalStack, Moto, or any AWS-compatible endpoint — just update `AWS_ENDPOINT_URL`.
74
+
75
+ ```bash
76
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.yml
77
+ docker compose up -d
78
+ # Open http://localhost:8080
79
+ ```
80
+
81
+ ### Docker (standalone)
82
+
83
+ ```bash
84
+ docker run -p 8080:8080 -e AWS_ENDPOINT_URL=http://host.docker.internal:4566 davireis/stackport
85
+ ```
86
+
87
+ ### Other emulators
88
+
89
+ StackPort works with any AWS-compatible endpoint — just set `AWS_ENDPOINT_URL`:
90
+
91
+ ```bash
92
+ # LocalStack
93
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
94
+
95
+ # Moto
96
+ AWS_ENDPOINT_URL=http://localhost:5000 stackport
97
+
98
+ # MinIO (S3 only)
99
+ AWS_ENDPOINT_URL=http://localhost:9000 stackport
100
+
101
+ # Any custom endpoint
102
+ AWS_ENDPOINT_URL=http://my-emulator:4566 stackport
103
+ ```
104
+
105
+ ### Multiple endpoints
106
+
107
+ Switch between multiple AWS endpoints from the UI. Configure named endpoints with `STACKPORT_ENDPOINTS`:
108
+
109
+ ```bash
110
+ # Connect to a local emulator and a real AWS account (empty URL = real AWS)
111
+ STACKPORT_ENDPOINTS="local=http://localhost:4566,nprod=" \
112
+ AWS_PROFILE=nprod AWS_REGION=us-west-1 stackport
113
+ ```
114
+
115
+ **Docker Compose (local + real AWS):**
116
+
117
+ ```bash
118
+ curl -O https://raw.githubusercontent.com/DaviReisVieira/stackport/main/examples/docker-compose.multi-endpoint.yml
119
+ docker compose -f docker-compose.multi-endpoint.yml up -d
120
+ # Open http://localhost:8080
121
+ ```
122
+
123
+ See [`examples/docker-compose.multi-endpoint.yml`](examples/docker-compose.multi-endpoint.yml) for a full example with MiniStack + real AWS via profile.
124
+
125
+ The endpoint selector appears in the sidebar when more than one endpoint is configured. Each endpoint is health-checked independently, and all API requests, caches, and WebSocket subscriptions are scoped to the active endpoint.
126
+
127
+ ## Service Browsers
128
+
129
+ ### Dedicated UIs (8 services)
130
+
131
+ | Service | Browse | Write Operations |
132
+ |---------|--------|-----------------|
133
+ | **S3** | Buckets, objects, folder navigation, search | Upload, download, delete, batch delete, create folders |
134
+ | **DynamoDB** | Tables, schema, items | Query by partition/sort key, scan |
135
+ | **Lambda** | Functions, config, aliases, versions, event sources | Invoke with JSON payload, download code |
136
+ | **SQS** | Queues, messages, attributes | Send, receive, delete messages, purge queue |
137
+ | **IAM** | Users, roles, groups, policies, trust policies | Read-only |
138
+ | **EC2** | Instances, VPCs, subnets, security groups, volumes | Read-only |
139
+ | **CloudWatch Logs** | Log groups, streams, events with time filtering | Read-only |
140
+ | **Secrets Manager** | Secrets with value reveal, rotation status | Read-only |
141
+
142
+ ### Generic Resource Browser (27 services)
143
+
144
+ All other services use a searchable resource table with JSON detail view, pagination, and export (JSON/CSV).
145
+
146
+ ## Tag Management
147
+
148
+ Unified tag read/write across 21 resource types:
149
+
150
+ S3 buckets, DynamoDB tables, Lambda functions, SQS queues, IAM users/roles/policies, EC2 instances/security groups/volumes, CloudWatch log groups, Secrets Manager secrets, RDS instances/clusters, SNS topics, KMS keys, ECR repositories, CloudFormation stacks, Step Functions state machines, Kinesis streams, SSM parameters, ELB load balancers, ElastiCache clusters
151
+
152
+ ## CLI
153
+
154
+ ```bash
155
+ # Show service availability and resource counts
156
+ stackport status
157
+ stackport status --output json
158
+
159
+ # List resources for a service
160
+ stackport list s3
161
+ stackport list dynamodb --output csv
162
+
163
+ # Get resource details
164
+ stackport describe s3 buckets my-bucket
165
+ stackport describe lambda functions my-func --output json
166
+
167
+ # Export all resources
168
+ stackport export lambda --format json
169
+ stackport export ec2 --format csv
170
+ ```
171
+
172
+ All CLI commands accept `--endpoint URL` and `--region REGION` overrides.
173
+
174
+ ## Keyboard Shortcuts
175
+
176
+ Press `?` anywhere to see all shortcuts.
177
+
178
+ | Key | Action |
179
+ |-----|--------|
180
+ | `?` | Show shortcuts modal |
181
+ | `b` | Toggle sidebar |
182
+ | `g d` | Go to Dashboard |
183
+ | `g r` | Go to Resources |
184
+ | `/` | Focus search |
185
+ | `j` / `k` | Navigate up/down in resource list |
186
+ | `[` / `]` | Previous/next service |
187
+ | `Enter` | Open selected resource |
188
+ | `r` | Refresh current view |
189
+ | `Esc` | Close panel / clear selection |
190
+
191
+ ## Configuration
192
+
193
+ | Variable | Default | Description |
194
+ |---|---|---|
195
+ | `AWS_ENDPOINT_URL` | *(unset)* | AWS endpoint. Unset = real AWS via credential chain |
196
+ | `AWS_REGION` | `us-east-1` | AWS region |
197
+ | `AWS_ACCESS_KEY_ID` | *(unset)* | AWS access key. Unset = use credential chain |
198
+ | `AWS_SECRET_ACCESS_KEY` | *(unset)* | AWS secret key. Unset = use credential chain |
199
+ | `AWS_PROFILE` | *(unset)* | AWS named profile from `~/.aws/credentials` |
200
+ | `STACKPORT_PORT` | `8080` | StackPort server port |
201
+ | `STACKPORT_ALLOW_WRITES` | `true` | Enable write operations (POST/PUT/DELETE) |
202
+ | `STACKPORT_S3_MAX_UPLOAD_MB` | `100` | Max S3 upload size per object (MiB) |
203
+ | `STACKPORT_SERVICES` | *(35 services)* | Comma-separated list of services to probe |
204
+ | `STACKPORT_PROBE_TIMEOUT` | `5` | Seconds before a service probe times out |
205
+ | `STACKPORT_CACHE_TTL` | `5` | Seconds to cache service stats |
206
+ | `STACKPORT_PROBE_WORKERS` | `10` | Max concurrent workers for service probing |
207
+ | `STACKPORT_ENDPOINTS` | *(unset)* | Multiple endpoints: `local=http://localhost:4566,staging=http://...` |
208
+ | `LOG_LEVEL` | `INFO` | Python log level (`DEBUG` shows healthcheck logs) |
209
+
210
+ ## Supported Services (35)
211
+
212
+ ACM, API Gateway, AppSync, Athena, CloudFormation, CloudFront, Cognito (IDP + Identity), DynamoDB, EC2, ECR, ECS, ElastiCache, EFS, ELB, EMR, EventBridge, Firehose, Glue, IAM, Kinesis, KMS, Lambda, CloudWatch Logs, CloudWatch Monitoring, RDS, Route 53, S3, Secrets Manager, SES, SNS, SQS, SSM, Step Functions, STS, WAFv2
213
+
214
+ ## Development
215
+
216
+ ```bash
217
+ git clone https://github.com/DaviReisVieira/stackport.git
218
+ cd stackport
219
+
220
+ # Backend
221
+ pip install -e .
222
+ AWS_ENDPOINT_URL=http://localhost:4566 stackport
223
+
224
+ # Frontend dev (with hot reload)
225
+ cd ui && npm install && npm run dev
226
+
227
+ # Build frontend for production
228
+ cd ui && npm run build
229
+
230
+ # Run tests
231
+ python -m pytest tests/ -x --tb=short # backend (262 tests)
232
+ cd ui && npx vitest run # frontend (163 tests)
233
+
234
+ # Typecheck & lint
235
+ cd ui && npx tsc -b
236
+ cd ui && npx eslint .
237
+ ```
238
+
239
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for full details.
240
+
241
+ ## Architecture
242
+
243
+ ```
244
+ backend/
245
+ main.py FastAPI app, CORS, read-only middleware, SPA mount
246
+ config.py All settings from environment variables
247
+ aws_client.py Cached boto3 client factory
248
+ cache.py Thread-safe TTL cache
249
+ websocket.py Real-time probe loop for dashboard
250
+ routes/
251
+ stats.py Service discovery with concurrent probing
252
+ resources.py Generic list/detail for all services
253
+ tags.py Unified tag management (21 types)
254
+ s3.py S3 file browser with write ops
255
+ dynamodb.py DynamoDB query/scan
256
+ lambda_svc.py Lambda invoke/config/code
257
+ sqs.py SQS send/receive/purge
258
+ iam.py IAM users/roles/groups/policies
259
+ ec2.py EC2 instances/VPCs/security groups
260
+ logs.py CloudWatch log streams/events
261
+ secretsmanager.py Secret value retrieval
262
+
263
+ ui/src/
264
+ pages/ Dashboard, ResourceBrowser, About
265
+ components/
266
+ service-views/ S3Browser, DynamoDBBrowser, LambdaBrowser, ...
267
+ ui/ shadcn/ui components (Radix-based)
268
+ hooks/ useFetch, useWebSocket, useKeyboardShortcuts, ...
269
+ lib/ API client, types, service icons, utils
270
+ ```
271
+
272
+ ## Star History
273
+
274
+ <a href="https://star-history.com/#DaviReisVieira/stackport&Date">
275
+ <picture>
276
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date&theme=dark" />
277
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date" />
278
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=DaviReisVieira/stackport&type=Date" width="100%" />
279
+ </picture>
280
+ </a>
281
+
282
+ ## Contributors
283
+
284
+ <a href="https://github.com/DaviReisVieira/stackport/graphs/contributors">
285
+ <img src="https://contrib.rocks/image?repo=DaviReisVieira/stackport" alt="Contributors" />
286
+ </a>
287
+
288
+ ## License
289
+
290
+ MIT
@@ -0,0 +1,42 @@
1
+ import functools
2
+
3
+ import boto3
4
+
5
+ from backend.config import (
6
+ AWS_ACCESS_KEY_ID,
7
+ AWS_REGION,
8
+ AWS_SECRET_ACCESS_KEY,
9
+ DEFAULT_ENDPOINT,
10
+ )
11
+
12
+ _UNSET = object()
13
+
14
+
15
+ @functools.lru_cache(maxsize=256)
16
+ def get_client(service_name: str, endpoint_url: str | None = _UNSET):
17
+ """Return a boto3 client for the given service and endpoint.
18
+
19
+ Args:
20
+ service_name: AWS service name (e.g., "s3", "dynamodb")
21
+ endpoint_url: Endpoint URL. None means real AWS (no custom endpoint).
22
+ Omitted (sentinel) means use DEFAULT_ENDPOINT.
23
+
24
+ Returns:
25
+ Configured boto3 client
26
+ """
27
+ url = DEFAULT_ENDPOINT if endpoint_url is _UNSET else endpoint_url
28
+
29
+ kwargs = {
30
+ "service_name": service_name,
31
+ "region_name": AWS_REGION,
32
+ }
33
+
34
+ if url is not None:
35
+ kwargs["endpoint_url"] = url
36
+
37
+ if AWS_ACCESS_KEY_ID is not None:
38
+ kwargs["aws_access_key_id"] = AWS_ACCESS_KEY_ID
39
+ if AWS_SECRET_ACCESS_KEY is not None:
40
+ kwargs["aws_secret_access_key"] = AWS_SECRET_ACCESS_KEY
41
+
42
+ return boto3.client(**kwargs)