mypackage-dev 0.1.0__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.
- mypackage_dev-0.1.0/LICENSE +21 -0
- mypackage_dev-0.1.0/PKG-INFO +330 -0
- mypackage_dev-0.1.0/README.md +303 -0
- mypackage_dev-0.1.0/pyproject.toml +53 -0
- mypackage_dev-0.1.0/src/mypackage/__init__.py +25 -0
- mypackage_dev-0.1.0/src/mypackage/calculator.py +93 -0
- mypackage_dev-0.1.0/src/mypackage/data_processor.py +78 -0
- mypackage_dev-0.1.0/src/mypackage/py.typed +1 -0
- mypackage_dev-0.1.0/src/mypackage/text_utils.py +62 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Your Name
|
|
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 NONINFRINGEMENT. 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,330 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mypackage-dev
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A sample Python package with semantic versioning for multiple environments (Development Environment)
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: sample,package,semantic-versioning
|
|
8
|
+
Author: Your Name
|
|
9
|
+
Author-email: your.email@example.com
|
|
10
|
+
Requires-Python: >=3.8,<4.0
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
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
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Project-URL: Documentation, https://github.com/yourusername/mypackage
|
|
23
|
+
Project-URL: Homepage, https://github.com/yourusername/mypackage
|
|
24
|
+
Project-URL: Repository, https://github.com/yourusername/mypackage
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# MyPackage
|
|
28
|
+
|
|
29
|
+
A production-ready Python package demonstrating best practices for packaging, semantic versioning, and multi-environment publishing to PyPI.
|
|
30
|
+
|
|
31
|
+
[](https://github.com/yourusername/mypackage/actions)
|
|
32
|
+
[](https://badge.fury.io/py/mypackage)
|
|
33
|
+
[](https://pypi.org/project/mypackage/)
|
|
34
|
+
[](https://opensource.org/licenses/MIT)
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
This package includes:
|
|
39
|
+
- 🧮 **Calculator**: Basic arithmetic operations (add, subtract, multiply, divide)
|
|
40
|
+
- 📝 **Text Utils**: String manipulation functions (capitalize, reverse, count words)
|
|
41
|
+
- 📊 **Data Processor**: List and number processing utilities (filter, sum, statistics)
|
|
42
|
+
|
|
43
|
+
## Multi-Environment Strategy
|
|
44
|
+
|
|
45
|
+
This package supports three environments with the **same version number** across all:
|
|
46
|
+
|
|
47
|
+
| Environment | Package Name | Purpose |
|
|
48
|
+
|------------|--------------|---------|
|
|
49
|
+
| **Production** | `mypackage` | Stable releases for production use |
|
|
50
|
+
| **QA** | `mypackage-qa` | Testing and quality assurance |
|
|
51
|
+
| **Development** | `mypackage-dev` | Latest development features |
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
### Production Environment
|
|
56
|
+
```bash
|
|
57
|
+
pip install mypackage
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### QA Environment
|
|
61
|
+
```bash
|
|
62
|
+
pip install mypackage-qa
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Development Environment
|
|
66
|
+
```bash
|
|
67
|
+
pip install mypackage-dev
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Quick Start
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from mypackage import add, subtract, capitalize_words, filter_even, get_statistics
|
|
74
|
+
|
|
75
|
+
# Calculator functions
|
|
76
|
+
result = add(10, 5) # 15
|
|
77
|
+
result = multiply(3, 4) # 12
|
|
78
|
+
|
|
79
|
+
# Text utilities
|
|
80
|
+
text = capitalize_words("hello world") # "Hello World"
|
|
81
|
+
reversed_text = reverse_string("Python") # "nohtyP"
|
|
82
|
+
|
|
83
|
+
# Data processing
|
|
84
|
+
evens = filter_even([1, 2, 3, 4, 5]) # [2, 4]
|
|
85
|
+
stats = get_statistics([1, 2, 3, 4, 5])
|
|
86
|
+
# {'min': 1, 'max': 5, 'mean': 3.0, 'sum': 15, 'count': 5}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Development Setup
|
|
90
|
+
|
|
91
|
+
### Prerequisites
|
|
92
|
+
- Python 3.8 or higher
|
|
93
|
+
- Poetry (for dependency management)
|
|
94
|
+
|
|
95
|
+
### Installation
|
|
96
|
+
|
|
97
|
+
1. Clone the repository:
|
|
98
|
+
```bash
|
|
99
|
+
git clone https://github.com/yourusername/mypackage.git
|
|
100
|
+
cd mypackage
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
2. Install dependencies using Poetry:
|
|
104
|
+
```bash
|
|
105
|
+
poetry install
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
3. Activate the virtual environment:
|
|
109
|
+
```bash
|
|
110
|
+
poetry shell
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Running Tests
|
|
114
|
+
|
|
115
|
+
Run all tests with coverage:
|
|
116
|
+
```bash
|
|
117
|
+
poetry run pytest
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Run specific test file:
|
|
121
|
+
```bash
|
|
122
|
+
poetry run pytest tests/test_calculator.py
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Code Quality
|
|
126
|
+
|
|
127
|
+
Format code:
|
|
128
|
+
```bash
|
|
129
|
+
poetry run black src tests scripts
|
|
130
|
+
poetry run isort src tests scripts
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Run linting:
|
|
134
|
+
```bash
|
|
135
|
+
poetry run flake8 src tests
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Type checking:
|
|
139
|
+
```bash
|
|
140
|
+
poetry run mypy src
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Run all validations:
|
|
144
|
+
```bash
|
|
145
|
+
python scripts/validate.py
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Semantic Versioning
|
|
149
|
+
|
|
150
|
+
This package follows [Semantic Versioning](https://semver.org/) (SemVer):
|
|
151
|
+
- **MAJOR** version for incompatible API changes
|
|
152
|
+
- **MINOR** version for backward-compatible functionality additions
|
|
153
|
+
- **PATCH** version for backward-compatible bug fixes
|
|
154
|
+
|
|
155
|
+
### Bumping Version
|
|
156
|
+
|
|
157
|
+
Use the provided script to bump versions:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Bump patch version (0.1.0 -> 0.1.1)
|
|
161
|
+
python scripts/bump_version.py patch
|
|
162
|
+
|
|
163
|
+
# Bump minor version (0.1.0 -> 0.2.0)
|
|
164
|
+
python scripts/bump_version.py minor
|
|
165
|
+
|
|
166
|
+
# Bump major version (0.1.0 -> 1.0.0)
|
|
167
|
+
python scripts/bump_version.py major
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The version will be automatically updated in:
|
|
171
|
+
- `pyproject.toml`
|
|
172
|
+
- `src/mypackage/__init__.py`
|
|
173
|
+
- Git tag will be created
|
|
174
|
+
|
|
175
|
+
## Publishing to PyPI
|
|
176
|
+
|
|
177
|
+
### Prerequisites
|
|
178
|
+
|
|
179
|
+
1. Create a PyPI account at [https://pypi.org](https://pypi.org)
|
|
180
|
+
2. Generate an API token from your PyPI account settings
|
|
181
|
+
3. Configure Poetry with your token:
|
|
182
|
+
```bash
|
|
183
|
+
poetry config pypi-token.pypi <your-token>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Publishing Process
|
|
187
|
+
|
|
188
|
+
1. **Validate your package**:
|
|
189
|
+
```bash
|
|
190
|
+
python scripts/validate.py
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
2. **Bump the version** (if needed):
|
|
194
|
+
```bash
|
|
195
|
+
python scripts/bump_version.py [major|minor|patch]
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
3. **Publish to specific environment**:
|
|
199
|
+
```bash
|
|
200
|
+
# Publish to dev
|
|
201
|
+
python scripts/publish.py dev
|
|
202
|
+
|
|
203
|
+
# Publish to qa
|
|
204
|
+
python scripts/publish.py qa
|
|
205
|
+
|
|
206
|
+
# Publish to prod
|
|
207
|
+
python scripts/publish.py prod
|
|
208
|
+
|
|
209
|
+
# Publish to all environments
|
|
210
|
+
python scripts/publish.py all
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
4. **Dry run** (test without publishing):
|
|
214
|
+
```bash
|
|
215
|
+
python scripts/publish.py all --dry-run
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Version Consistency
|
|
219
|
+
|
|
220
|
+
The same version number is maintained across all three environments (dev, qa, prod). Only the package name differs:
|
|
221
|
+
- `mypackage-dev` version 0.1.0
|
|
222
|
+
- `mypackage-qa` version 0.1.0
|
|
223
|
+
- `mypackage` version 0.1.0
|
|
224
|
+
|
|
225
|
+
## Project Structure
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
first_python_package/
|
|
229
|
+
├── src/
|
|
230
|
+
│ └── mypackage/
|
|
231
|
+
│ ├── __init__.py
|
|
232
|
+
│ ├── calculator.py
|
|
233
|
+
│ ├── text_utils.py
|
|
234
|
+
│ └── data_processor.py
|
|
235
|
+
├── tests/
|
|
236
|
+
│ ├── __init__.py
|
|
237
|
+
│ ├── test_calculator.py
|
|
238
|
+
│ ├── test_text_utils.py
|
|
239
|
+
│ └── test_data_processor.py
|
|
240
|
+
├── scripts/
|
|
241
|
+
│ ├── bump_version.py
|
|
242
|
+
│ ├── publish.py
|
|
243
|
+
│ └── validate.py
|
|
244
|
+
├── .github/
|
|
245
|
+
│ └── workflows/
|
|
246
|
+
│ └── ci.yml
|
|
247
|
+
├── pyproject.toml
|
|
248
|
+
├── .bumpversion.cfg
|
|
249
|
+
├── .gitignore
|
|
250
|
+
├── .pre-commit-config.yaml
|
|
251
|
+
├── LICENSE
|
|
252
|
+
└── README.md
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## API Documentation
|
|
256
|
+
|
|
257
|
+
### Calculator Module
|
|
258
|
+
|
|
259
|
+
- `add(a, b)` - Add two numbers
|
|
260
|
+
- `subtract(a, b)` - Subtract b from a
|
|
261
|
+
- `multiply(a, b)` - Multiply two numbers
|
|
262
|
+
- `divide(a, b)` - Divide a by b (raises ValueError if b is zero)
|
|
263
|
+
|
|
264
|
+
### Text Utils Module
|
|
265
|
+
|
|
266
|
+
- `capitalize_words(text)` - Capitalize first letter of each word
|
|
267
|
+
- `reverse_string(text)` - Reverse a string
|
|
268
|
+
- `count_words(text)` - Count words in a string
|
|
269
|
+
|
|
270
|
+
### Data Processor Module
|
|
271
|
+
|
|
272
|
+
- `filter_even(numbers)` - Filter even numbers from a list
|
|
273
|
+
- `sum_list(numbers)` - Calculate sum of numbers
|
|
274
|
+
- `get_statistics(numbers)` - Get min, max, mean, sum, and count
|
|
275
|
+
|
|
276
|
+
## CI/CD Pipeline
|
|
277
|
+
|
|
278
|
+
The project includes a GitHub Actions workflow that:
|
|
279
|
+
- Runs on Python 3.8, 3.9, 3.10, 3.11, and 3.12
|
|
280
|
+
- Executes linting and type checking
|
|
281
|
+
- Runs all tests with coverage reporting
|
|
282
|
+
- Validates the package build
|
|
283
|
+
- (Optional) Automatically publishes on version tags
|
|
284
|
+
|
|
285
|
+
## Contributing
|
|
286
|
+
|
|
287
|
+
1. Fork the repository
|
|
288
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
289
|
+
3. Make your changes
|
|
290
|
+
4. Run tests and validation (`python scripts/validate.py`)
|
|
291
|
+
5. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
292
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
293
|
+
7. Open a Pull Request
|
|
294
|
+
|
|
295
|
+
## Best Practices Implemented
|
|
296
|
+
|
|
297
|
+
✅ **Poetry** for modern dependency management
|
|
298
|
+
✅ **Semantic Versioning** with automated version bumping
|
|
299
|
+
✅ **Multi-environment** support (dev, qa, prod)
|
|
300
|
+
✅ **Type hints** throughout the codebase
|
|
301
|
+
✅ **Comprehensive test suite** with pytest
|
|
302
|
+
✅ **Code quality tools** (black, isort, flake8, mypy)
|
|
303
|
+
✅ **Pre-commit hooks** for automated checks
|
|
304
|
+
✅ **CI/CD pipeline** with GitHub Actions
|
|
305
|
+
✅ **Detailed documentation** with examples
|
|
306
|
+
✅ **Proper package structure** following Python standards
|
|
307
|
+
|
|
308
|
+
## License
|
|
309
|
+
|
|
310
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
311
|
+
|
|
312
|
+
## Changelog
|
|
313
|
+
|
|
314
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
315
|
+
|
|
316
|
+
## Support
|
|
317
|
+
|
|
318
|
+
For issues and questions:
|
|
319
|
+
- 🐛 [Report bugs](https://github.com/yourusername/mypackage/issues)
|
|
320
|
+
- 💡 [Request features](https://github.com/yourusername/mypackage/issues)
|
|
321
|
+
- 📧 Email: your.email@example.com
|
|
322
|
+
|
|
323
|
+
## Acknowledgments
|
|
324
|
+
|
|
325
|
+
This package was created as a demonstration of Python packaging best practices, including:
|
|
326
|
+
- Multi-environment deployment strategy
|
|
327
|
+
- Semantic versioning
|
|
328
|
+
- Modern tooling with Poetry
|
|
329
|
+
- Comprehensive testing and validation
|
|
330
|
+
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# MyPackage
|
|
2
|
+
|
|
3
|
+
A production-ready Python package demonstrating best practices for packaging, semantic versioning, and multi-environment publishing to PyPI.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/yourusername/mypackage/actions)
|
|
6
|
+
[](https://badge.fury.io/py/mypackage)
|
|
7
|
+
[](https://pypi.org/project/mypackage/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
This package includes:
|
|
13
|
+
- 🧮 **Calculator**: Basic arithmetic operations (add, subtract, multiply, divide)
|
|
14
|
+
- 📝 **Text Utils**: String manipulation functions (capitalize, reverse, count words)
|
|
15
|
+
- 📊 **Data Processor**: List and number processing utilities (filter, sum, statistics)
|
|
16
|
+
|
|
17
|
+
## Multi-Environment Strategy
|
|
18
|
+
|
|
19
|
+
This package supports three environments with the **same version number** across all:
|
|
20
|
+
|
|
21
|
+
| Environment | Package Name | Purpose |
|
|
22
|
+
|------------|--------------|---------|
|
|
23
|
+
| **Production** | `mypackage` | Stable releases for production use |
|
|
24
|
+
| **QA** | `mypackage-qa` | Testing and quality assurance |
|
|
25
|
+
| **Development** | `mypackage-dev` | Latest development features |
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
### Production Environment
|
|
30
|
+
```bash
|
|
31
|
+
pip install mypackage
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### QA Environment
|
|
35
|
+
```bash
|
|
36
|
+
pip install mypackage-qa
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Development Environment
|
|
40
|
+
```bash
|
|
41
|
+
pip install mypackage-dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from mypackage import add, subtract, capitalize_words, filter_even, get_statistics
|
|
48
|
+
|
|
49
|
+
# Calculator functions
|
|
50
|
+
result = add(10, 5) # 15
|
|
51
|
+
result = multiply(3, 4) # 12
|
|
52
|
+
|
|
53
|
+
# Text utilities
|
|
54
|
+
text = capitalize_words("hello world") # "Hello World"
|
|
55
|
+
reversed_text = reverse_string("Python") # "nohtyP"
|
|
56
|
+
|
|
57
|
+
# Data processing
|
|
58
|
+
evens = filter_even([1, 2, 3, 4, 5]) # [2, 4]
|
|
59
|
+
stats = get_statistics([1, 2, 3, 4, 5])
|
|
60
|
+
# {'min': 1, 'max': 5, 'mean': 3.0, 'sum': 15, 'count': 5}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Development Setup
|
|
64
|
+
|
|
65
|
+
### Prerequisites
|
|
66
|
+
- Python 3.8 or higher
|
|
67
|
+
- Poetry (for dependency management)
|
|
68
|
+
|
|
69
|
+
### Installation
|
|
70
|
+
|
|
71
|
+
1. Clone the repository:
|
|
72
|
+
```bash
|
|
73
|
+
git clone https://github.com/yourusername/mypackage.git
|
|
74
|
+
cd mypackage
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
2. Install dependencies using Poetry:
|
|
78
|
+
```bash
|
|
79
|
+
poetry install
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
3. Activate the virtual environment:
|
|
83
|
+
```bash
|
|
84
|
+
poetry shell
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Running Tests
|
|
88
|
+
|
|
89
|
+
Run all tests with coverage:
|
|
90
|
+
```bash
|
|
91
|
+
poetry run pytest
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run specific test file:
|
|
95
|
+
```bash
|
|
96
|
+
poetry run pytest tests/test_calculator.py
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Code Quality
|
|
100
|
+
|
|
101
|
+
Format code:
|
|
102
|
+
```bash
|
|
103
|
+
poetry run black src tests scripts
|
|
104
|
+
poetry run isort src tests scripts
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Run linting:
|
|
108
|
+
```bash
|
|
109
|
+
poetry run flake8 src tests
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Type checking:
|
|
113
|
+
```bash
|
|
114
|
+
poetry run mypy src
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Run all validations:
|
|
118
|
+
```bash
|
|
119
|
+
python scripts/validate.py
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Semantic Versioning
|
|
123
|
+
|
|
124
|
+
This package follows [Semantic Versioning](https://semver.org/) (SemVer):
|
|
125
|
+
- **MAJOR** version for incompatible API changes
|
|
126
|
+
- **MINOR** version for backward-compatible functionality additions
|
|
127
|
+
- **PATCH** version for backward-compatible bug fixes
|
|
128
|
+
|
|
129
|
+
### Bumping Version
|
|
130
|
+
|
|
131
|
+
Use the provided script to bump versions:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Bump patch version (0.1.0 -> 0.1.1)
|
|
135
|
+
python scripts/bump_version.py patch
|
|
136
|
+
|
|
137
|
+
# Bump minor version (0.1.0 -> 0.2.0)
|
|
138
|
+
python scripts/bump_version.py minor
|
|
139
|
+
|
|
140
|
+
# Bump major version (0.1.0 -> 1.0.0)
|
|
141
|
+
python scripts/bump_version.py major
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The version will be automatically updated in:
|
|
145
|
+
- `pyproject.toml`
|
|
146
|
+
- `src/mypackage/__init__.py`
|
|
147
|
+
- Git tag will be created
|
|
148
|
+
|
|
149
|
+
## Publishing to PyPI
|
|
150
|
+
|
|
151
|
+
### Prerequisites
|
|
152
|
+
|
|
153
|
+
1. Create a PyPI account at [https://pypi.org](https://pypi.org)
|
|
154
|
+
2. Generate an API token from your PyPI account settings
|
|
155
|
+
3. Configure Poetry with your token:
|
|
156
|
+
```bash
|
|
157
|
+
poetry config pypi-token.pypi <your-token>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Publishing Process
|
|
161
|
+
|
|
162
|
+
1. **Validate your package**:
|
|
163
|
+
```bash
|
|
164
|
+
python scripts/validate.py
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
2. **Bump the version** (if needed):
|
|
168
|
+
```bash
|
|
169
|
+
python scripts/bump_version.py [major|minor|patch]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
3. **Publish to specific environment**:
|
|
173
|
+
```bash
|
|
174
|
+
# Publish to dev
|
|
175
|
+
python scripts/publish.py dev
|
|
176
|
+
|
|
177
|
+
# Publish to qa
|
|
178
|
+
python scripts/publish.py qa
|
|
179
|
+
|
|
180
|
+
# Publish to prod
|
|
181
|
+
python scripts/publish.py prod
|
|
182
|
+
|
|
183
|
+
# Publish to all environments
|
|
184
|
+
python scripts/publish.py all
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
4. **Dry run** (test without publishing):
|
|
188
|
+
```bash
|
|
189
|
+
python scripts/publish.py all --dry-run
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Version Consistency
|
|
193
|
+
|
|
194
|
+
The same version number is maintained across all three environments (dev, qa, prod). Only the package name differs:
|
|
195
|
+
- `mypackage-dev` version 0.1.0
|
|
196
|
+
- `mypackage-qa` version 0.1.0
|
|
197
|
+
- `mypackage` version 0.1.0
|
|
198
|
+
|
|
199
|
+
## Project Structure
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
first_python_package/
|
|
203
|
+
├── src/
|
|
204
|
+
│ └── mypackage/
|
|
205
|
+
│ ├── __init__.py
|
|
206
|
+
│ ├── calculator.py
|
|
207
|
+
│ ├── text_utils.py
|
|
208
|
+
│ └── data_processor.py
|
|
209
|
+
├── tests/
|
|
210
|
+
│ ├── __init__.py
|
|
211
|
+
│ ├── test_calculator.py
|
|
212
|
+
│ ├── test_text_utils.py
|
|
213
|
+
│ └── test_data_processor.py
|
|
214
|
+
├── scripts/
|
|
215
|
+
│ ├── bump_version.py
|
|
216
|
+
│ ├── publish.py
|
|
217
|
+
│ └── validate.py
|
|
218
|
+
├── .github/
|
|
219
|
+
│ └── workflows/
|
|
220
|
+
│ └── ci.yml
|
|
221
|
+
├── pyproject.toml
|
|
222
|
+
├── .bumpversion.cfg
|
|
223
|
+
├── .gitignore
|
|
224
|
+
├── .pre-commit-config.yaml
|
|
225
|
+
├── LICENSE
|
|
226
|
+
└── README.md
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## API Documentation
|
|
230
|
+
|
|
231
|
+
### Calculator Module
|
|
232
|
+
|
|
233
|
+
- `add(a, b)` - Add two numbers
|
|
234
|
+
- `subtract(a, b)` - Subtract b from a
|
|
235
|
+
- `multiply(a, b)` - Multiply two numbers
|
|
236
|
+
- `divide(a, b)` - Divide a by b (raises ValueError if b is zero)
|
|
237
|
+
|
|
238
|
+
### Text Utils Module
|
|
239
|
+
|
|
240
|
+
- `capitalize_words(text)` - Capitalize first letter of each word
|
|
241
|
+
- `reverse_string(text)` - Reverse a string
|
|
242
|
+
- `count_words(text)` - Count words in a string
|
|
243
|
+
|
|
244
|
+
### Data Processor Module
|
|
245
|
+
|
|
246
|
+
- `filter_even(numbers)` - Filter even numbers from a list
|
|
247
|
+
- `sum_list(numbers)` - Calculate sum of numbers
|
|
248
|
+
- `get_statistics(numbers)` - Get min, max, mean, sum, and count
|
|
249
|
+
|
|
250
|
+
## CI/CD Pipeline
|
|
251
|
+
|
|
252
|
+
The project includes a GitHub Actions workflow that:
|
|
253
|
+
- Runs on Python 3.8, 3.9, 3.10, 3.11, and 3.12
|
|
254
|
+
- Executes linting and type checking
|
|
255
|
+
- Runs all tests with coverage reporting
|
|
256
|
+
- Validates the package build
|
|
257
|
+
- (Optional) Automatically publishes on version tags
|
|
258
|
+
|
|
259
|
+
## Contributing
|
|
260
|
+
|
|
261
|
+
1. Fork the repository
|
|
262
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
263
|
+
3. Make your changes
|
|
264
|
+
4. Run tests and validation (`python scripts/validate.py`)
|
|
265
|
+
5. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
266
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
267
|
+
7. Open a Pull Request
|
|
268
|
+
|
|
269
|
+
## Best Practices Implemented
|
|
270
|
+
|
|
271
|
+
✅ **Poetry** for modern dependency management
|
|
272
|
+
✅ **Semantic Versioning** with automated version bumping
|
|
273
|
+
✅ **Multi-environment** support (dev, qa, prod)
|
|
274
|
+
✅ **Type hints** throughout the codebase
|
|
275
|
+
✅ **Comprehensive test suite** with pytest
|
|
276
|
+
✅ **Code quality tools** (black, isort, flake8, mypy)
|
|
277
|
+
✅ **Pre-commit hooks** for automated checks
|
|
278
|
+
✅ **CI/CD pipeline** with GitHub Actions
|
|
279
|
+
✅ **Detailed documentation** with examples
|
|
280
|
+
✅ **Proper package structure** following Python standards
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
285
|
+
|
|
286
|
+
## Changelog
|
|
287
|
+
|
|
288
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
|
289
|
+
|
|
290
|
+
## Support
|
|
291
|
+
|
|
292
|
+
For issues and questions:
|
|
293
|
+
- 🐛 [Report bugs](https://github.com/yourusername/mypackage/issues)
|
|
294
|
+
- 💡 [Request features](https://github.com/yourusername/mypackage/issues)
|
|
295
|
+
- 📧 Email: your.email@example.com
|
|
296
|
+
|
|
297
|
+
## Acknowledgments
|
|
298
|
+
|
|
299
|
+
This package was created as a demonstration of Python packaging best practices, including:
|
|
300
|
+
- Multi-environment deployment strategy
|
|
301
|
+
- Semantic versioning
|
|
302
|
+
- Modern tooling with Poetry
|
|
303
|
+
- Comprehensive testing and validation
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = [ "poetry-core",]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
[tool.poetry]
|
|
6
|
+
name = "mypackage-dev"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A sample Python package with semantic versioning for multiple environments (Development Environment)"
|
|
9
|
+
authors = [ "Your Name <your.email@example.com>",]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
homepage = "https://github.com/yourusername/mypackage"
|
|
13
|
+
repository = "https://github.com/yourusername/mypackage"
|
|
14
|
+
documentation = "https://github.com/yourusername/mypackage"
|
|
15
|
+
keywords = [ "sample", "package", "semantic-versioning",]
|
|
16
|
+
classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12",]
|
|
17
|
+
[[tool.poetry.packages]]
|
|
18
|
+
include = "mypackage"
|
|
19
|
+
from = "src"
|
|
20
|
+
|
|
21
|
+
[tool.black]
|
|
22
|
+
line-length = 88
|
|
23
|
+
target-version = [ "py38",]
|
|
24
|
+
include = "\\.pyi?$"
|
|
25
|
+
|
|
26
|
+
[tool.isort]
|
|
27
|
+
profile = "black"
|
|
28
|
+
line_length = 88
|
|
29
|
+
|
|
30
|
+
[tool.mypy]
|
|
31
|
+
python_version = "3.8"
|
|
32
|
+
warn_return_any = true
|
|
33
|
+
warn_unused_configs = true
|
|
34
|
+
disallow_untyped_defs = true
|
|
35
|
+
|
|
36
|
+
[tool.poetry.dependencies]
|
|
37
|
+
python = "^3.8"
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
testpaths = [ "tests",]
|
|
41
|
+
python_files = "test_*.py"
|
|
42
|
+
python_functions = "test_*"
|
|
43
|
+
addopts = "-v --cov=mypackage --cov-report=term-missing --cov-report=html"
|
|
44
|
+
|
|
45
|
+
[tool.poetry.group.dev.dependencies]
|
|
46
|
+
pytest = "^7.4.0"
|
|
47
|
+
pytest-cov = "^4.1.0"
|
|
48
|
+
black = "^23.7.0"
|
|
49
|
+
isort = "^5.12.0"
|
|
50
|
+
flake8 = "^6.1.0"
|
|
51
|
+
mypy = "^1.5.0"
|
|
52
|
+
pre-commit = "^3.3.3"
|
|
53
|
+
bump2version = "^1.0.1"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MyPackage - A sample Python package with semantic versioning.
|
|
3
|
+
|
|
4
|
+
This package demonstrates best practices for creating and publishing
|
|
5
|
+
Python packages to PyPI with support for multiple environments.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
|
|
10
|
+
from .calculator import add, subtract, multiply, divide
|
|
11
|
+
from .text_utils import capitalize_words, reverse_string, count_words
|
|
12
|
+
from .data_processor import filter_even, sum_list, get_statistics
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"add",
|
|
16
|
+
"subtract",
|
|
17
|
+
"multiply",
|
|
18
|
+
"divide",
|
|
19
|
+
"capitalize_words",
|
|
20
|
+
"reverse_string",
|
|
21
|
+
"count_words",
|
|
22
|
+
"filter_even",
|
|
23
|
+
"sum_list",
|
|
24
|
+
"get_statistics",
|
|
25
|
+
]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Calculator module providing basic arithmetic operations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Number = Union[int, float]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def add(a: Number, b: Number) -> Number:
|
|
12
|
+
"""
|
|
13
|
+
Add two numbers.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
a: First number
|
|
17
|
+
b: Second number
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
Sum of a and b
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> add(2, 3)
|
|
24
|
+
5
|
|
25
|
+
>>> add(2.5, 3.5)
|
|
26
|
+
6.0
|
|
27
|
+
"""
|
|
28
|
+
return a + b
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def subtract(a: Number, b: Number) -> Number:
|
|
32
|
+
"""
|
|
33
|
+
Subtract second number from first number.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
a: First number
|
|
37
|
+
b: Second number
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Difference of a and b
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
>>> subtract(5, 3)
|
|
44
|
+
2
|
|
45
|
+
>>> subtract(10.5, 3.5)
|
|
46
|
+
7.0
|
|
47
|
+
"""
|
|
48
|
+
return a - b
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def multiply(a: Number, b: Number) -> Number:
|
|
52
|
+
"""
|
|
53
|
+
Multiply two numbers.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
a: First number
|
|
57
|
+
b: Second number
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Product of a and b
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
>>> multiply(2, 3)
|
|
64
|
+
6
|
|
65
|
+
>>> multiply(2.5, 4)
|
|
66
|
+
10.0
|
|
67
|
+
"""
|
|
68
|
+
return a * b
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def divide(a: Number, b: Number) -> float:
|
|
72
|
+
"""
|
|
73
|
+
Divide first number by second number.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
a: Numerator
|
|
77
|
+
b: Denominator
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Quotient of a and b
|
|
81
|
+
|
|
82
|
+
Raises:
|
|
83
|
+
ValueError: If b is zero
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
>>> divide(6, 3)
|
|
87
|
+
2.0
|
|
88
|
+
>>> divide(10, 4)
|
|
89
|
+
2.5
|
|
90
|
+
"""
|
|
91
|
+
if b == 0:
|
|
92
|
+
raise ValueError("Cannot divide by zero")
|
|
93
|
+
return a / b
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data processing utilities for working with lists and numbers.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import List, Dict, Union
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Number = Union[int, float]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def filter_even(numbers: List[int]) -> List[int]:
|
|
12
|
+
"""
|
|
13
|
+
Filter even numbers from a list.
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
numbers: List of integers
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
List containing only even numbers
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
>>> filter_even([1, 2, 3, 4, 5, 6])
|
|
23
|
+
[2, 4, 6]
|
|
24
|
+
>>> filter_even([1, 3, 5])
|
|
25
|
+
[]
|
|
26
|
+
"""
|
|
27
|
+
return [num for num in numbers if num % 2 == 0]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def sum_list(numbers: List[Number]) -> Number:
|
|
31
|
+
"""
|
|
32
|
+
Calculate the sum of numbers in a list.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
numbers: List of numbers
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Sum of all numbers
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
>>> sum_list([1, 2, 3, 4, 5])
|
|
42
|
+
15
|
|
43
|
+
>>> sum_list([1.5, 2.5, 3.0])
|
|
44
|
+
7.0
|
|
45
|
+
"""
|
|
46
|
+
return sum(numbers)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_statistics(numbers: List[Number]) -> Dict[str, Number]:
|
|
50
|
+
"""
|
|
51
|
+
Calculate basic statistics for a list of numbers.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
numbers: List of numbers
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Dictionary containing min, max, mean, and sum
|
|
58
|
+
|
|
59
|
+
Raises:
|
|
60
|
+
ValueError: If the list is empty
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
>>> stats = get_statistics([1, 2, 3, 4, 5])
|
|
64
|
+
>>> stats['mean']
|
|
65
|
+
3.0
|
|
66
|
+
>>> stats['max']
|
|
67
|
+
5
|
|
68
|
+
"""
|
|
69
|
+
if not numbers:
|
|
70
|
+
raise ValueError("Cannot calculate statistics for an empty list")
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
"min": min(numbers),
|
|
74
|
+
"max": max(numbers),
|
|
75
|
+
"mean": sum(numbers) / len(numbers),
|
|
76
|
+
"sum": sum(numbers),
|
|
77
|
+
"count": len(numbers),
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# This file marks the package as PEP 561 compliant for type checking
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Text utility functions for string manipulation.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def capitalize_words(text: str) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Capitalize the first letter of each word in a string.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
text: Input string
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
String with each word capitalized
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> capitalize_words("hello world")
|
|
18
|
+
'Hello World'
|
|
19
|
+
>>> capitalize_words("python programming")
|
|
20
|
+
'Python Programming'
|
|
21
|
+
"""
|
|
22
|
+
return text.title()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def reverse_string(text: str) -> str:
|
|
26
|
+
"""
|
|
27
|
+
Reverse a string.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
text: Input string
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Reversed string
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
>>> reverse_string("hello")
|
|
37
|
+
'olleh'
|
|
38
|
+
>>> reverse_string("Python")
|
|
39
|
+
'nohtyP'
|
|
40
|
+
"""
|
|
41
|
+
return text[::-1]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def count_words(text: str) -> int:
|
|
45
|
+
"""
|
|
46
|
+
Count the number of words in a string.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
text: Input string
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Number of words in the string
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
>>> count_words("hello world")
|
|
56
|
+
2
|
|
57
|
+
>>> count_words("Python is awesome")
|
|
58
|
+
3
|
|
59
|
+
"""
|
|
60
|
+
if not text or text.isspace():
|
|
61
|
+
return 0
|
|
62
|
+
return len(text.split())
|