fastgram-cli 0.1.6__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.
@@ -0,0 +1,23 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ groups:
8
+ actions:
9
+ patterns:
10
+ - "*"
11
+ commit-message:
12
+ prefix: ⬆️
13
+
14
+ - package-ecosystem: "uv"
15
+ directory: "/"
16
+ schedule:
17
+ interval: monthly
18
+ groups:
19
+ python-deps:
20
+ patterns:
21
+ - "*"
22
+ commit-message:
23
+ prefix: ⬆️
@@ -0,0 +1,58 @@
1
+ name: Cleanup Workflow Runs
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 * * 0'
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ actions: write
10
+ contents: read
11
+
12
+ jobs:
13
+ cleanup:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Delete old workflow runs
17
+ uses: actions/github-script@v8
18
+ with:
19
+ script: |
20
+ const workflowRuns = await github.rest.actions.listWorkflowRuns({
21
+ owner: context.repo.owner,
22
+ repo: context.repo.repo,
23
+ status: 'completed',
24
+ per_page: 100
25
+ });
26
+
27
+ let deleted = 0;
28
+ const toKeep = 10; // Keep last 10 runs per workflow
29
+
30
+ // Group by workflow
31
+ const runsByWorkflow = {};
32
+ for (const run of workflowRuns.data.workflow_runs) {
33
+ if (!runsByWorkflow[run.workflow_id]) {
34
+ runsByWorkflow[run.workflow_id] = [];
35
+ }
36
+ runsByWorkflow[run.workflow_id].push(run);
37
+ }
38
+
39
+ // Delete old runs
40
+ for (const [workflowId, runs] of Object.entries(runsByWorkflow)) {
41
+ if (runs.length > toKeep) {
42
+ const oldRuns = runs.slice(toKeep);
43
+ for (const run of oldRuns) {
44
+ try {
45
+ await github.rest.actions.deleteWorkflowRun({
46
+ owner: context.repo.owner,
47
+ repo: context.repo.repo,
48
+ run_id: run.id
49
+ });
50
+ deleted++;
51
+ } catch (e) {
52
+ console.log(`Failed to delete run ${run.id}: ${e.message}`);
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ console.log(`Deleted ${deleted} old workflow runs`);
@@ -0,0 +1,83 @@
1
+ name: Release & Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout repository
16
+ uses: actions/checkout@v6
17
+ with:
18
+ fetch-depth: 0
19
+ token: ${{ secrets.GITHUB_TOKEN }}
20
+
21
+ - name: Get version from pyproject
22
+ id: version
23
+ run: |
24
+ VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
25
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
26
+ echo "version=$VERSION" >> $GITHUB_ENV
27
+
28
+ - name: Check if tag already exists
29
+ id: tag_check
30
+ run: |
31
+ TAG="v${{ env.version }}"
32
+ if git rev-parse "$TAG" >/dev/null 2>&1; then
33
+ echo "Tag $TAG already exists, skipping release"
34
+ echo "skip=true" >> $GITHUB_OUTPUT
35
+ else
36
+ echo "skip=false" >> $GITHUB_OUTPUT
37
+ fi
38
+
39
+ - name: Create tag and release
40
+ if: steps.tag_check.outputs.skip == 'false'
41
+ run: |
42
+ TAG="v${{ env.version }}"
43
+
44
+ git config user.name "github-actions[bot]"
45
+ git config user.email "github-actions[bot]@users.noreply.github.com"
46
+ git tag "$TAG"
47
+ git push origin "$TAG"
48
+
49
+ - name: Create GitHub Release
50
+ if: steps.tag_check.outputs.skip == 'false'
51
+ uses: softprops/action-gh-release@v2
52
+ with:
53
+ tag_name: v${{ env.version }}
54
+ name: v${{ env.version }}
55
+ generate_release_notes: true
56
+ draft: false
57
+ prerelease: false
58
+ env:
59
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60
+
61
+ - name: Set up Python
62
+ if: steps.tag_check.outputs.skip == 'false'
63
+ uses: actions/setup-python@v6
64
+ with:
65
+ python-version: '3.11'
66
+
67
+ - name: Install dependencies
68
+ if: steps.tag_check.outputs.skip == 'false'
69
+ run: |
70
+ python -m pip install --upgrade pip
71
+ pip install build twine
72
+
73
+ - name: Build package
74
+ if: steps.tag_check.outputs.skip == 'false'
75
+ run: python -m build
76
+
77
+ - name: Publish to PyPI
78
+ if: steps.tag_check.outputs.skip == 'false'
79
+ env:
80
+ TWINE_USERNAME: __token__
81
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
82
+ run: |
83
+ twine upload dist/*
@@ -0,0 +1,46 @@
1
+ name: Welcome Bot
2
+
3
+ on:
4
+ issues:
5
+ types: [opened]
6
+ pull_request:
7
+ types: [opened]
8
+
9
+ permissions:
10
+ issues: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ welcome:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Welcome contributor
18
+ uses: actions/github-script@v8
19
+ with:
20
+ script: |
21
+ const { issue, pull_request, sender } = context.payload;
22
+
23
+ let message;
24
+
25
+ if (issue) {
26
+ // Issue opened
27
+ message = `👋 **Thanks @${sender.login}** for opening this issue! 🎉\n\nWe'll review it soon. Please make sure to:\n- Use a descriptive title\n- Include steps to reproduce if it's a bug\n- Check existing issues before creating a new one\n\nLooking forward to your contribution! ❤️`;
28
+
29
+ await github.rest.issues.createComment({
30
+ owner: context.repo.owner,
31
+ repo: context.repo.repo,
32
+ issue_number: issue.number,
33
+ body: message
34
+ });
35
+
36
+ } else if (pull_request) {
37
+ // PR opened
38
+ message = `👋 **Thanks @${sender.login}** for this contribution! 🚀\n\nWe're excited to review your PR.\n\n💡 **Tips:**\n- Keep your PR focused and atomic\n- Add tests if applicable\n- Update docs if needed\n\nHappy coding! ✨`;
39
+
40
+ await github.rest.issues.createComment({
41
+ owner: context.repo.owner,
42
+ repo: context.repo.repo,
43
+ issue_number: pull_request.number,
44
+ body: message
45
+ });
46
+ }
@@ -0,0 +1,10 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
@@ -0,0 +1,36 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.6.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - id: check-yaml
8
+ - id: check-json
9
+ - id: check-added-large-files
10
+ args: ['--maxkb=1000']
11
+ - id: detect-private-key
12
+
13
+
14
+ - repo: https://github.com/astral-sh/ruff-pre-commit
15
+ rev: v0.8.2
16
+ hooks:
17
+ - id: ruff
18
+ args: [--fix]
19
+ - id: ruff-format
20
+
21
+ - repo: https://github.com/pre-commit/mirrors-mypy
22
+ rev: v1.14.0
23
+ hooks:
24
+ - id: mypy
25
+ additional_dependencies: [typer, rich]
26
+ args: [--strict, --ignore-missing-imports]
27
+
28
+
29
+ - repo: https://github.com/pypa/pip-audit
30
+ rev: v2.7.3
31
+ hooks:
32
+ - id: pip-audit
33
+
34
+ ci:
35
+ autoupdate_commit_msg: "chore: update pre-commit hooks"
36
+ skip: [pip-audit]
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,116 @@
1
+ # Contributing to fastgram
2
+
3
+ Thank you for your interest in contributing! We welcome contributions from the community.
4
+
5
+ ## How to Contribute
6
+
7
+ ### 1. Fork the Repository
8
+
9
+ Fork the repository on GitHub and clone it locally:
10
+
11
+ ```bash
12
+ git clone https://github.com/ndugram/fastgram-cli.git
13
+ cd fastgram
14
+ ```
15
+
16
+ ### 2. Set Up Development Environment
17
+
18
+ ```bash
19
+ # Create virtual environment
20
+ python -m venv venv
21
+ source venv/bin/activate # On Windows: venv\Scripts\activate
22
+
23
+ # Install dependencies
24
+ pip install -e ".[dev]"
25
+
26
+ # Install pre-commit hooks
27
+ pre-commit install
28
+ ```
29
+
30
+ ### 3. Make Your Changes
31
+
32
+ - Create a new branch for your feature or bugfix
33
+ - Write clean, documented code
34
+ - Add tests for your changes
35
+ - Ensure all tests pass
36
+
37
+ ### 4. Submit a Pull Request
38
+
39
+ 1. Push your changes to your fork
40
+ 2. Open a Pull Request against the `main` branch
41
+ 3. Fill in the PR template completely
42
+ 4. Link any related issues
43
+
44
+ ## Code Style
45
+
46
+ - Follow [PEP 8](https://pep8.org/) guidelines
47
+ - Use type hints for all functions
48
+ - Write docstrings for public functions
49
+ - Keep lines under 100 characters
50
+
51
+ ### Linting and Formatting
52
+
53
+ ```bash
54
+ # Run linter
55
+ ruff check .
56
+
57
+ # Format code
58
+ ruff format .
59
+
60
+ # Run type checker
61
+ mypy src/
62
+ ```
63
+
64
+ ## Testing
65
+
66
+ ```bash
67
+ # Run all tests
68
+ pytest
69
+
70
+ # Run with coverage
71
+ pytest --cov=src
72
+ ```
73
+
74
+ ## Commit Messages
75
+
76
+ Follow the [Conventional Commits](https://www.conventionalcommits.org/) format:
77
+
78
+ ```
79
+ <type>(<scope>): <description>
80
+
81
+ body (optional)
82
+
83
+ footer (optional)
84
+ ```
85
+
86
+ Types:
87
+ - `feat` - New feature
88
+ - `fix` - Bug fix
89
+ - `docs` - Documentation changes
90
+ - `style` - Code style changes
91
+ - `refactor` - Code refactoring
92
+ - `test` - Adding tests
93
+ - `chore` - Maintenance tasks
94
+
95
+ Example:
96
+ ```
97
+ feat(ssl): add certificate expiration warning
98
+
99
+ Add a warning when certificates are about to expire within 30 days.
100
+
101
+ Closes #123
102
+ ```
103
+
104
+ ## Issue Tracking
105
+
106
+ - Before submitting an issue, search existing issues to avoid duplicates
107
+ - Use the issue template when creating a new issue
108
+ - Provide as much detail as possible (steps to reproduce, expected vs actual behavior)
109
+
110
+ ## Questions?
111
+
112
+ If you have questions, feel free to:
113
+ - Open a [Discussion](https://github.com/ndugram/fastgram-cli/discussions)
114
+ - Ask in our community chat
115
+
116
+ We appreciate your contribution!
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 安𝐍ᴇғᴏʀ | ᵈᵉᵛ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFREMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,255 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastgram-cli
3
+ Version: 0.1.6
4
+ Summary: CLI tool for FastAPI - generate SSL certificates and more
5
+ Project-URL: Homepage, https://github.com/ndugram/fastgram-cli
6
+ Project-URL: Repository, https://github.com/ndugram/fastgram-cli
7
+ Project-URL: Issues, https://github.com/ndugram/fastgram-cli/issues
8
+ Author-email: NEFORCEO <n7for8572@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: certificate,cli,fastgram,ssl,tool
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: aiosqlite>=0.22.1
23
+ Requires-Dist: fastapi>=0.128.0
24
+ Requires-Dist: python-jose[cryptography]>=3.3.0
25
+ Requires-Dist: rich>=14.2.0
26
+ Requires-Dist: sqlalchemy>=2.0.45
27
+ Requires-Dist: typer>=0.21.1
28
+ Requires-Dist: uvicorn>=0.27.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # fastgram
32
+
33
+ A modern CLI tool for FastAPI developers - initialize projects with middleware, manage settings, and generate SSL certificates.
34
+
35
+ ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
36
+ ![License](https://img.shields.io/badge/license-MIT-green)
37
+ ![PyPI Version](https://img.shields.io/badge/pypi-latest-blue)
38
+
39
+ ## Features
40
+
41
+ - 🚀 Initialize FastAPI project structure with Django-like folder layout
42
+ - 🔐 Generate self-signed SSL certificates
43
+ - 📦 Pre-configured middleware (CORS, Request ID, Logging, Rate Limit)
44
+ - ⚙️ Centralized settings (server, middleware, rate limits)
45
+ - 💅 Beautiful output with Rich library
46
+ - ⚡ Fast and easy to use
47
+ - 📦 Ready for PyPI publication
48
+
49
+ ## Installation
50
+
51
+
52
+ ### From GitHub
53
+
54
+ ```bash
55
+ pip install git+https://github.com/ndugram/fastgram-cli.git
56
+ ```
57
+
58
+ ### From Source
59
+
60
+ ```bash
61
+ git clone https://github.com/ndugram/fastgram-cli.git
62
+ cd fastgram
63
+ pip install -e .
64
+ ```
65
+
66
+ ## Quick Start
67
+
68
+ ```bash
69
+ # Initialize a new project
70
+ fastgram init myproject
71
+
72
+ # Enter project directory
73
+ cd myproject
74
+
75
+ # Start development server
76
+ python manage.py runserver
77
+
78
+ # Open in browser
79
+ # http://127.0.0.1:8000
80
+ # API docs: http://127.0.0.1:8000/docs
81
+ ```
82
+
83
+ ## Initialize Project
84
+
85
+ ```bash
86
+ fastgram init [name]
87
+ ```
88
+
89
+ Creates a new FastAPI project structure with pre-configured middleware:
90
+
91
+ ```
92
+ project_name/
93
+ ├── api/
94
+ │ └── __init__.py
95
+ ├── core/
96
+ │ └── __init__.py
97
+ ├── database/
98
+ │ └── __init__.py
99
+ ├── schema/
100
+ │ └── __init__.py
101
+ ├── service/
102
+ │ └── __init__.py
103
+ ├── views/
104
+ │ └── __init__.py
105
+ ├── middleware/
106
+ │ ├── __init__.py
107
+ │ ├── cors.py
108
+ │ ├── logging.py
109
+ │ ├── rate_limit.py
110
+ │ ├── request_id.py
111
+ │ └── loader.py
112
+ ├── main.py
113
+ ├── manage.py
114
+ └── settings.py
115
+ ```
116
+
117
+ Default project name: `backend`
118
+
119
+ ## Middleware
120
+
121
+ Generated projects include these middleware by default:
122
+
123
+ | Middleware | Description |
124
+ |------------|-------------|
125
+ | `RateLimitMiddleware` | Rate limiting (default: 5 requests/second) |
126
+ | `LoggingMiddleware` | Logs incoming HTTP requests |
127
+ | `CORSMiddleware` | Cross-Origin Resource Sharing (permissive) |
128
+ | `RequestIDMiddleware` | Adds unique request ID to each request |
129
+
130
+ ### Configure Middleware
131
+
132
+ Edit `settings.py` to modify middleware:
133
+
134
+ ```python
135
+ MIDDLEWARE = [
136
+ "middleware.rate_limit.RateLimitMiddleware",
137
+ "middleware.logging.LoggingMiddleware",
138
+ "middleware.cors.CORSMiddleware",
139
+ "middleware.request_id.RequestIDMiddleware",
140
+ ]
141
+ ```
142
+
143
+ ### Rate Limit Settings
144
+
145
+ Configure rate limiting in `settings.py`:
146
+
147
+ ```python
148
+ RATE_LIMIT_LIMIT = "5/second" # Format: "<count>/<second|minute>"
149
+ ```
150
+
151
+ ## Settings
152
+
153
+ All configuration is centralized in `settings.py`:
154
+
155
+ ```python
156
+
157
+ SECRET_KEY = "generated_secret_key_here"
158
+
159
+ # Database settings
160
+ DB_URL = "sqlite+aiosqlite:///./db.sqlite3"
161
+
162
+ # Server settings
163
+ HOST = "127.0.0.1"
164
+ PORT = 8000
165
+ RELOAD = True
166
+
167
+ # Rate limit settings
168
+ RATE_LIMIT_LIMIT = "5/second"
169
+
170
+ # Middleware registration
171
+ MIDDLEWARE = [
172
+ "middleware.rate_limit.RateLimitMiddleware",
173
+ "middleware.logging.LoggingMiddleware",
174
+ "middleware.cors.CORSMiddleware",
175
+ "middleware.request_id.RequestIDMiddleware",
176
+ ]
177
+ ```
178
+
179
+ ## Generate SSL Certificates
180
+
181
+ Creates SSL certificates in `certs/` directory:
182
+ - `certs/cert.pem` - SSL certificate
183
+ - `certs/key.pem` - Private key
184
+
185
+ ## Commands
186
+
187
+ | Command | Description |
188
+ |---------|-------------|
189
+ | `init [name]` | Initialize FastAPI project structure |
190
+ | `ssl` | Generate self-signed SSL certificates |
191
+ | `help` | Show available commands |
192
+
193
+ ## manage.py Commands
194
+
195
+ After initializing a project, use `manage.py` for development tasks:
196
+
197
+ ```bash
198
+ cd myproject
199
+ ```
200
+
201
+ ### Run Development Server
202
+
203
+ ```bash
204
+ python manage.py runserver # Default: 127.0.0.1:8000
205
+ python manage.py runserver --host 0.0.0.0 # Bind to all interfaces
206
+ python manage.py runserver --port 8080 # Custom port
207
+ python manage.py runserver --noreload # Disable auto-reload
208
+ ```
209
+
210
+ ### Database Migration
211
+
212
+ ```bash
213
+ python manage.py migrate # Create database tables
214
+ ```
215
+
216
+ ### Show Help
217
+
218
+ ```bash
219
+ python manage.py help
220
+ ```
221
+
222
+ ## Project Structure
223
+
224
+ Generated projects follow a clean architecture:
225
+
226
+ ```
227
+ myproject/
228
+ ├── api/ # API route handlers
229
+ ├── core/ # Core application settings
230
+ ├── database/ # Database models and connections
231
+ ├── middleware/ # Custom middleware (CORS, Logging, Rate Limit, etc.)
232
+ ├── schema/ # Pydantic schemas
233
+ ├── service/ # Business logic
234
+ ├── views/ # View controllers
235
+ ├── main.py # FastAPI application entry point
236
+ ├── manage.py # Django-like management script
237
+ └── settings.py # Centralized configuration
238
+ ```
239
+
240
+ ## Requirements
241
+
242
+ - Python 3.10+
243
+ - OpenSSL (for SSL certificate generation)
244
+
245
+ ## Contributing
246
+
247
+ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
248
+
249
+ ## Security
250
+
251
+ For security issues, please read our [Security Policy](SECURITY.md).
252
+
253
+ ## License
254
+
255
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.