aboutsummaryrefslogtreecommitdiff
path: root/generate_json.py
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2025-08-25 18:27:47 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2025-08-27 11:46:25 +0200
commit372f52e13ad01512a35a1538a0a765dff7711095 (patch)
tree46ff73141191062e3d9636ff5989eca307ba7e43 /generate_json.py
parent8e478e06c2c09e8d74fcaa6cca84f7db14d23265 (diff)
improve python experience
Diffstat (limited to 'generate_json.py')
-rw-r--r--generate_json.py169
1 files changed, 106 insertions, 63 deletions
diff --git a/generate_json.py b/generate_json.py
index b3e285f..2f0a9d5 100644
--- a/generate_json.py
+++ b/generate_json.py
@@ -7,23 +7,23 @@ import sys
import os
from datetime import datetime
-def random_string(length):
- """Generate a random string of given length."""
- return ''.join(random.choices(string.ascii_letters + string.digits + ' ', k=length))
-def random_email():
- """Generate a random email address."""
- username = ''.join(random.choices(string.ascii_lowercase, k=random.randint(5, 12)))
- domain = ''.join(random.choices(string.ascii_lowercase, k=random.randint(4, 8)))
- tld = random.choice(['com', 'org', 'net', 'edu', 'gov'])
+def random_string(length: int) -> str:
+ return "".join(random.choices(string.ascii_letters + string.digits + " ", k=length))
+
+
+def random_email() -> str:
+ username = "".join(random.choices(string.ascii_lowercase, k=random.randint(5, 12)))
+ domain = "".join(random.choices(string.ascii_lowercase, k=random.randint(4, 8)))
+ tld = random.choice(["com", "org", "net", "edu", "gov"])
return f"{username}@{domain}.{tld}"
-def random_phone():
- """Generate a random phone number."""
+
+def random_phone() -> str:
return f"+1-{random.randint(100, 999)}-{random.randint(100, 999)}-{random.randint(1000, 9999)}"
+
def generate_user():
- """Generate a random user object."""
return {
"id": random.randint(1, 1000000),
"username": random_string(random.randint(6, 15)),
@@ -34,38 +34,44 @@ def generate_user():
"phone": random_phone(),
"is_active": random.choice([True, False]),
"balance": round(random.uniform(0, 10000), 2),
- "tags": [random_string(random.randint(3, 8)) for _ in range(random.randint(1, 5))],
+ "tags": [
+ random_string(random.randint(3, 8)) for _ in range(random.randint(1, 5))
+ ],
"metadata": {
"last_login": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
"login_count": random.randint(0, 500),
"preferences": {
"theme": random.choice(["dark", "light", "auto"]),
"notifications": random.choice([True, False]),
- "language": random.choice(["en", "es", "fr", "de", "ja"])
- }
- }
+ "language": random.choice(["en", "es", "fr", "de", "ja"]),
+ },
+ },
}
+
def generate_product():
- """Generate a random product object."""
return {
"id": f"prod_{random.randint(1000, 99999)}",
"name": random_string(random.randint(10, 30)),
"description": random_string(random.randint(50, 200)),
"price": round(random.uniform(1, 1000), 2),
- "category": random.choice(["electronics", "clothing", "books", "home", "sports", "toys"]),
+ "category": random.choice(
+ ["electronics", "clothing", "books", "home", "sports", "toys"]
+ ),
"in_stock": random.randint(0, 100),
"rating": round(random.uniform(1, 5), 1),
"reviews": random.randint(0, 1000),
"specifications": {
"weight": f"{random.uniform(0.1, 50):.2f}kg",
"dimensions": f"{random.randint(1, 100)}x{random.randint(1, 100)}x{random.randint(1, 100)}cm",
- "color": random.choice(["red", "blue", "green", "black", "white", "yellow", "purple"])
- }
+ "color": random.choice(
+ ["red", "blue", "green", "black", "white", "yellow", "purple"]
+ ),
+ },
}
+
def generate_order():
- """Generate a random order object."""
return {
"order_id": f"order_{random.randint(10000, 999999)}",
"user_id": random.randint(1, 1000000),
@@ -73,38 +79,38 @@ def generate_order():
{
"product_id": f"prod_{random.randint(1000, 99999)}",
"quantity": random.randint(1, 5),
- "price": round(random.uniform(10, 500), 2)
- } for _ in range(random.randint(1, 8))
+ "price": round(random.uniform(10, 500), 2),
+ }
+ for _ in range(random.randint(1, 8))
],
"total": round(random.uniform(20, 2000), 2),
- "status": random.choice(["pending", "processing", "shipped", "delivered", "cancelled"]),
+ "status": random.choice(
+ ["pending", "processing", "shipped", "delivered", "cancelled"]
+ ),
"created_at": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
"shipping_address": {
"street": f"{random.randint(1, 9999)} {random_string(random.randint(5, 15))} St",
"city": random_string(random.randint(6, 12)),
"state": random_string(2).upper(),
"zip_code": f"{random.randint(10000, 99999)}",
- "country": "US"
- }
+ "country": "US",
+ },
}
-def generate_large_json(target_size_mb=100, output_file="benchmark.json"):
- """Generate a large JSON file with mixed data types."""
+
+def generate_large_json(target_size_mb: int, output_file: str):
target_size_bytes = target_size_mb * 1024 * 1024
data = {
"metadata": {
"generated_at": datetime.now().isoformat(),
"target_size_mb": target_size_mb,
- "generator_version": "1.0"
+ "generator_version": "1.0",
},
"users": [],
"products": [],
"orders": [],
- "analytics": {
- "page_views": [],
- "server_metrics": []
- }
+ "analytics": {"page_views": [], "server_metrics": []},
}
print(f"Generating JSON file targeting {target_size_mb}MB...")
@@ -128,37 +134,43 @@ def generate_large_json(target_size_mb=100, output_file="benchmark.json"):
# Add some analytics data
for _ in range(batch_size):
- data["analytics"]["page_views"].append({
- "timestamp": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
- "page": f"/{random_string(random.randint(5, 15))}",
- "user_id": random.randint(1, 1000000),
- "duration": random.randint(1, 300)
- })
+ data["analytics"]["page_views"].append(
+ {
+ "timestamp": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
+ "page": f"/{random_string(random.randint(5, 15))}",
+ "user_id": random.randint(1, 1000000),
+ "duration": random.randint(1, 300),
+ }
+ )
for _ in range(batch_size // 10):
- data["analytics"]["server_metrics"].append({
- "timestamp": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
- "cpu_usage": round(random.uniform(0, 100), 2),
- "memory_usage": round(random.uniform(0, 100), 2),
- "disk_io": random.randint(0, 1000),
- "network_io": random.randint(0, 10000)
- })
+ data["analytics"]["server_metrics"].append(
+ {
+ "timestamp": f"2024-{random.randint(1, 12):02d}-{random.randint(1, 28):02d}T{random.randint(0, 23):02d}:{random.randint(0, 59):02d}:{random.randint(0, 59):02d}Z",
+ "cpu_usage": round(random.uniform(0, 100), 2),
+ "memory_usage": round(random.uniform(0, 100), 2),
+ "disk_io": random.randint(0, 1000),
+ "network_io": random.randint(0, 10000),
+ }
+ )
# Estimate current size (rough approximation)
current_size = (
- len(data["users"]) * 400 + # Rough estimate per user
- len(data["products"]) * 300 +
- len(data["orders"]) * 500 +
- len(data["analytics"]["page_views"]) * 150 +
- len(data["analytics"]["server_metrics"]) * 200
+ len(data["users"]) * 400 # Rough estimate per user
+ + len(data["products"]) * 300
+ + len(data["orders"]) * 500
+ + len(data["analytics"]["page_views"]) * 150
+ + len(data["analytics"]["server_metrics"]) * 200
)
- if current_size % (10 * 1024 * 1024) < batch_size * 400: # Print progress every ~10MB
+ if (
+ current_size % (10 * 1024 * 1024) < batch_size * 400
+ ): # Print progress every ~10MB
print(f"Generated approximately {current_size / (1024 * 1024):.1f}MB...")
print(f"Writing to {output_file}...")
- with open(output_file, 'w') as f:
- json.dump(data, f, separators=(',', ':')) # Compact format
+ with open(output_file, "w") as f:
+ json.dump(data, f, separators=(",", ":")) # Compact format
# Get actual file size
actual_size = os.path.getsize(output_file)
@@ -173,24 +185,55 @@ def generate_large_json(target_size_mb=100, output_file="benchmark.json"):
print(f" Page views: {len(data['analytics']['page_views']):,}")
print(f" Server metrics: {len(data['analytics']['server_metrics']):,}")
+def generate_descriptive(target_size_mb: int, output_file: str):
+ target_size_bytes = target_size_mb * 1024 * 1024
+ data = []
+ current_size = 0
+ batch_size = 100
+
+ print(f"Generating descriptive JSON array targeting {target_size_mb}MB...")
+
+ while current_size < target_size_bytes:
+ batch = [
+ {
+ "name": random_string(40),
+ "description": random_string(400),
+ }
+ for _ in range(batch_size)
+ ]
+ data.extend(batch)
+ # Estimate current size (approximate: 40+400 chars per object + overhead)
+ current_size = len(data) * (40 + 400 + 30)
+
+ if (
+ current_size % (10 * 1024 * 1024) < batch_size * (40 + 400)
+ ):
+ print(f"Generated approximately {current_size / (1024 * 1024):.1f}MB...")
+
+ print(f"Writing to {output_file}...")
+ with open(output_file, "w") as f:
+ json.dump(data, f, separators=(",", ":"))
+
+ actual_size = os.path.getsize(output_file)
+ actual_size_mb = actual_size / (1024 * 1024)
+
+ print(f"✓ Generated {output_file}")
+ print(f" Target size: {target_size_mb}MB")
+ print(f" Actual size: {actual_size_mb:.1f}MB ({actual_size:,} bytes)")
+ print(f" Objects: {len(data):,}")
+
def main():
assert len(sys.argv) == 2
try:
target_size = int(sys.argv[1])
except ValueError:
- print("Usage: python3 generate_json.py [size_in_mb] [output_file]")
+ print("Usage: python3 generate_json.py [size_in_mb]")
sys.exit(1)
- output_file = f"{target_size}MB.json"
+ output_file = f"descriptive-{target_size}MB.json"
+
+ generate_descriptive(target_size, output_file)
- try:
- generate_large_json(target_size, output_file)
- except KeyboardInterrupt:
- print("\n\nInterrupted! Partial file may have been created.")
- sys.exit(1)
- except Exception as e:
- print(f"Error: {e}")
- sys.exit(1)
if __name__ == "__main__":
main()