f1pitwall 1.0.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.
@@ -0,0 +1,13 @@
1
+ .DS_Store
2
+ cache/
3
+ .mplconfig/
4
+ __pycache__/
5
+ *.pyc
6
+ .env
7
+ .f1token
8
+ venv/
9
+ .venv/
10
+ *.egg-info/
11
+ dist/
12
+ build/
13
+ .gstack/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Darsh Joshi
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,474 @@
1
+ Metadata-Version: 2.4
2
+ Name: f1pitwall
3
+ Version: 1.0.0
4
+ Summary: Turn Claude into your F1 race engineer — 67 MCP tools for telemetry, strategy, and 75 years of race history
5
+ Project-URL: Homepage, https://github.com/darshjoshi/pitwall
6
+ Project-URL: Repository, https://github.com/darshjoshi/pitwall
7
+ Project-URL: Issues, https://github.com/darshjoshi/pitwall/issues
8
+ Author-email: Darsh Joshi <contact@darshjoshi.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: claude,f1,fastf1,formula1,mcp,model-context-protocol,motorsport,race-data,telemetry
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
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
+ Classifier: Topic :: Scientific/Engineering
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: mcp>=1.0.0
25
+ Requires-Dist: requests>=2.28.0
26
+ Provides-Extra: full
27
+ Requires-Dist: aiohttp>=3.9.0; extra == 'full'
28
+ Requires-Dist: certifi; extra == 'full'
29
+ Requires-Dist: fastf1>=3.0.0; extra == 'full'
30
+ Requires-Dist: matplotlib>=3.7.0; extra == 'full'
31
+ Requires-Dist: numpy>=1.24.0; extra == 'full'
32
+ Requires-Dist: pandas>=2.0.0; extra == 'full'
33
+ Requires-Dist: pyjwt>=2.0.0; extra == 'full'
34
+ Requires-Dist: websockets>=13.0; extra == 'full'
35
+ Description-Content-Type: text/markdown
36
+
37
+ <h1 align="center">Pitwall</h1>
38
+
39
+ <p align="center">
40
+ <strong>Turn Claude into your F1 race engineer.</strong><br>
41
+ Real telemetry. Real strategy data. Real-time during races. 75 years of history.
42
+ </p>
43
+
44
+ <p align="center">
45
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
46
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/Python-3.10+-green.svg" alt="Python 3.10+"></a>
47
+ <a href="https://modelcontextprotocol.io"><img src="https://img.shields.io/badge/MCP-Compatible-purple.svg" alt="MCP Compatible"></a>
48
+ <a href="https://github.com/darshjoshi/pitwall/stargazers"><img src="https://img.shields.io/github/stars/darshjoshi/pitwall?style=social" alt="GitHub Stars"></a>
49
+ </p>
50
+
51
+ <p align="center">
52
+ <img src="assets/ver_vs_nor_abu_dhabi_2024_quali.png" alt="Verstappen vs Norris — Abu Dhabi 2024 Qualifying Speed Trace" width="700">
53
+ </p>
54
+
55
+ ---
56
+
57
+ ## Quick Start
58
+
59
+ ```bash
60
+ pip install f1pitwall
61
+ claude mcp add pitwall -- f1pitwall
62
+ ```
63
+
64
+ Then ask Claude: *"Who won the 2025 Australian GP?"*
65
+
66
+ > Want visual plots and deep analysis? `pip install "f1pitwall[full]"`
67
+
68
+ <details>
69
+ <summary><strong>Install from source instead</strong></summary>
70
+
71
+ ```bash
72
+ git clone https://github.com/darshjoshi/pitwall.git && cd pitwall
73
+ pip install "mcp[cli]" requests # lite
74
+ pip install -r requirements-full.txt # full
75
+ claude mcp add pitwall -- python3 $(pwd)/pitwall.py
76
+ ```
77
+
78
+ </details>
79
+
80
+ ---
81
+
82
+ ## Why Pitwall?
83
+
84
+ Claude knows F1 from training data — but it can't look up last week's race. It can't show you Verstappen's throttle trace through Turn 1. It doesn't know who pitted first or when the safety car came out.
85
+
86
+ Pitwall connects Claude to **live F1 data**:
87
+
88
+ - **Real data, not hallucinations** — actual timing feeds from formula1.com
89
+ - **Lap-level telemetry** — speed, RPM, throttle, brake, gear, DRS at 4Hz per car
90
+ - **Visual plots** — speed trace comparisons, gear shift maps returned as images
91
+ - **75 years of history** — every race result and championship since 1950
92
+ - **Live during races** — real-time positions, gaps, weather, and race control
93
+ - **Zero API keys** — all core data is free, no account needed
94
+
95
+ ---
96
+
97
+ ## What You Can Ask
98
+
99
+ ```
100
+ "Who won the 2025 Australian GP?" → Race results and classification
101
+ "Verstappen's speed on lap 25 at Monaco" → Lap telemetry at 4Hz
102
+ "Plot Hamilton vs Norris speed trace" → Visual speed comparison chart
103
+ "Compare Ferrari's tyre strategy" → Stint-by-stint breakdown
104
+ "Who won the 1994 championship?" → 75 years of history
105
+ "When was the safety car at Silverstone?" → Race control messages and flags
106
+ ```
107
+
108
+ <details>
109
+ <summary><strong>See all example questions</strong></summary>
110
+
111
+ | Question | Tool Used |
112
+ |----------|-----------|
113
+ | "Who won the Chinese GP?" | `get_standings` |
114
+ | "What was Verstappen's speed on lap 25?" | `get_telemetry` |
115
+ | "Compare Hamilton vs Leclerc" | `get_driver_comparison` |
116
+ | "What tyres did everyone use?" | `get_tyre_strategy` |
117
+ | "Fastest pit stop at Australia 2025?" | `get_pit_stops` |
118
+ | "When was the safety car?" | `get_race_control` |
119
+ | "Was it raining during the race?" | `get_weather` |
120
+ | "Top speeds at Monza 2024?" | `get_speed_traps` |
121
+ | "Norris's lap times in the race" | `get_lap_times` |
122
+ | "Who won the 2005 championship?" | `get_championship_standings` |
123
+ | "Plot Verstappen vs Hamilton speed trace" | `plot_telemetry_comparison` |
124
+ | "Show me the gear shift map at Monaco" | `plot_gear_shifts` |
125
+ | "Who gained the most positions?" | `compare_grid_to_finish` |
126
+ | "Overtakes in the race" | `detect_overtakes` |
127
+ | "Compare Verstappen lap 5 vs lap 50" | `plot_multi_telemetry_comparison` |
128
+ | "Ferrari head-to-head in qualifying" | `team_head_to_head` |
129
+ | "Deleted laps in qualifying" | `get_deleted_laps` |
130
+ | "Gap to leader throughout the race" | `get_gap_to_leader` |
131
+
132
+ </details>
133
+
134
+ ---
135
+
136
+ ## Features
137
+
138
+ **67 tools** across two modes. Pitwall auto-detects what's installed — no config changes needed.
139
+
140
+ ### Lite Mode (14 tools)
141
+
142
+ `pip install "mcp[cli]" requests` — no heavy dependencies.
143
+
144
+ Race results, lap times, telemetry, tyre strategy, pit stops, weather, race control, speed traps, driver comparison, and historical data back to 1950. Uses F1's free static archive and the Jolpica API.
145
+
146
+ ### Full Mode (67 tools)
147
+
148
+ `pip install -r requirements-full.txt` — adds [FastF1](https://github.com/theOehrly/Fast-F1).
149
+
150
+ Everything in Lite, plus:
151
+
152
+ | Category | What You Get |
153
+ |----------|-------------|
154
+ | **Visual Plots** | Speed trace comparisons, gear shift maps, multi-lap telemetry overlays |
155
+ | **Deep Telemetry** | Brake point analysis, RPM patterns, DRS usage, throttle traces |
156
+ | **Advanced Strategy** | Stint degradation, compound comparisons, tire age performance |
157
+ | **Race Intelligence** | Overtake detection, gap tracking, position changes, qualifying progression |
158
+ | **Live Data** | Real-time positions, lap times, sector times, weather during active sessions |
159
+
160
+ <details>
161
+ <summary><strong>Full tool list (67 tools)</strong></summary>
162
+
163
+ #### Lite Tools (always available)
164
+ | Tool | Description |
165
+ |------|-------------|
166
+ | `list_seasons` | Available seasons (2018-present) |
167
+ | `list_races` | Full season calendar with dates |
168
+ | `get_race_info` | Session details and available data feeds |
169
+ | `get_standings` | Race classification — positions, gaps, best laps, pits |
170
+ | `get_lap_times` | Lap-by-lap times, filterable by driver and lap range |
171
+ | `get_telemetry` | Speed, RPM, throttle, brake, gear, DRS for a specific lap |
172
+ | `get_tyre_strategy` | Compound, stint length, new/used for every driver |
173
+ | `get_pit_stops` | All pit stops sorted by fastest |
174
+ | `get_race_control` | Flags, penalties, safety cars, investigations |
175
+ | `get_weather` | Air/track temp, rain, humidity, wind |
176
+ | `get_speed_traps` | Speed at 4 measurement points per driver |
177
+ | `get_driver_comparison` | Head-to-head: position, pace, strategy, pit stops |
178
+ | `get_historical_results` | Race results from 1950 to present |
179
+ | `get_championship_standings` | Driver/constructor championships from 1950+ |
180
+
181
+ #### FastF1 Tools (requires FastF1)
182
+ | Category | Tools |
183
+ |----------|-------|
184
+ | **Visual Plots** | `plot_telemetry_comparison`, `plot_gear_shifts`, `plot_multi_telemetry_comparison`, `plot_driver_telemetry_comparison` |
185
+ | **Telemetry Analysis** | `analyze_brake_points`, `analyze_rpm_data`, `analyze_drs_usage` |
186
+ | **Lap Analysis** | `get_lap_times_fastf1`, `get_deleted_laps`, `analyze_lap_consistency`, `get_fastest_sectors`, `get_personal_best_laps`, `compare_sector_times` |
187
+ | **Strategy** | `get_driver_tyre_detail`, `get_stint_analysis`, `compare_tire_compounds`, `compare_tire_age_performance`, `analyze_starting_tires`, `compare_strategies` |
188
+ | **Race Analysis** | `get_race_results`, `get_sprint_results`, `get_session_summary`, `get_fastest_lap_data`, `detect_overtakes`, `compare_grid_to_finish`, `get_qualifying_progression` |
189
+ | **Pit Stops** | `get_pit_stop_detail`, `get_fastest_pit_stops` |
190
+ | **Driver & Team** | `get_driver_info`, `get_driver_standings`, `get_constructor_standings`, `team_head_to_head`, `get_team_laps`, `analyze_long_run_pace` |
191
+ | **Track & Safety** | `get_circuit_info`, `get_track_status`, `get_track_record`, `get_race_control_messages`, `get_penalties`, `get_dnf_list` |
192
+ | **Speed & Position** | `get_speed_trap_comparison`, `get_position_changes`, `get_gap_to_leader` |
193
+ | **History** | `get_race_winners_history` |
194
+ | **Live Data** | `get_live_session_status`, `get_live_positions`, `get_live_lap_times`, `get_live_sector_times`, `get_live_telemetry`, `get_live_weather` |
195
+ | **Session** | `get_schedule`, `get_session_info`, `get_weather_data` |
196
+
197
+ </details>
198
+
199
+ ---
200
+
201
+ ## Setup
202
+
203
+ <details>
204
+ <summary><strong>macOS</strong></summary>
205
+
206
+ **Claude Code:**
207
+ ```bash
208
+ claude mcp add pitwall -- python3 /absolute/path/to/pitwall.py
209
+ ```
210
+
211
+ **Claude Desktop** — add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
212
+ ```json
213
+ {
214
+ "mcpServers": {
215
+ "pitwall": {
216
+ "command": "python3",
217
+ "args": ["/absolute/path/to/pitwall.py"]
218
+ }
219
+ }
220
+ }
221
+ ```
222
+ </details>
223
+
224
+ <details>
225
+ <summary><strong>Windows</strong></summary>
226
+
227
+ **1. Find your Python path:**
228
+ ```cmd
229
+ where python
230
+ ```
231
+ This will return something like `C:\Users\YourName\AppData\Local\Programs\Python\Python313\python.exe` or `C:\Python313\python.exe`.
232
+
233
+ **2. Note where you cloned Pitwall:**
234
+ For example: `C:\Users\YourName\Projects\pitwall\pitwall.py`
235
+
236
+ **Claude Code (PowerShell):**
237
+ ```powershell
238
+ claude mcp add pitwall -- python C:\Users\YourName\Projects\pitwall\pitwall.py
239
+ ```
240
+
241
+ **Claude Desktop** — add to `%APPDATA%\Claude\claude_desktop_config.json`:
242
+
243
+ > To open this folder, press `Win + R`, type `%APPDATA%\Claude`, and hit Enter. If the `Claude` folder or `claude_desktop_config.json` doesn't exist, create them.
244
+
245
+ ```json
246
+ {
247
+ "mcpServers": {
248
+ "pitwall": {
249
+ "command": "python",
250
+ "args": ["C:\\Users\\YourName\\Projects\\pitwall\\pitwall.py"]
251
+ }
252
+ }
253
+ }
254
+ ```
255
+
256
+ > **Note:** Use double backslashes (`\\`) in the JSON path, or forward slashes (`/`) — both work. The command is `python` (not `python3`) on Windows.
257
+ </details>
258
+
259
+ <details>
260
+ <summary><strong>Linux</strong></summary>
261
+
262
+ **Claude Code:**
263
+ ```bash
264
+ claude mcp add pitwall -- python3 /absolute/path/to/pitwall.py
265
+ ```
266
+
267
+ **Claude Desktop** — add to `~/.config/Claude/claude_desktop_config.json`:
268
+ ```json
269
+ {
270
+ "mcpServers": {
271
+ "pitwall": {
272
+ "command": "python3",
273
+ "args": ["/absolute/path/to/pitwall.py"]
274
+ }
275
+ }
276
+ }
277
+ ```
278
+ </details>
279
+
280
+ Restart Claude Code or Claude Desktop after setup. Works with any MCP-compatible client.
281
+
282
+ ### Optional: Beginner-Friendly Skill (Claude Desktop)
283
+
284
+ Upload `SKILL.md` as a skill in Claude Desktop (Settings → Skills → Upload). Claude will explain F1 jargon inline — DRS, undercut, compound, safety car, etc.
285
+
286
+ ---
287
+
288
+ ## Data Sources
289
+
290
+ All core data is **free and requires no API keys**.
291
+
292
+ | Source | Coverage | What it provides |
293
+ |--------|----------|-----------------|
294
+ | [F1 Static Live Timing](https://livetiming.formula1.com/static/) | 2018-present | Telemetry, timing, strategy, pit stops, weather, race control |
295
+ | [Jolpica-F1](https://api.jolpi.ca/ergast/f1/) | 1950-present | Historical results and championships |
296
+ | [FastF1](https://github.com/theOehrly/Fast-F1) (optional) | 2018-present | Enhanced telemetry analysis and visual plots |
297
+ | [F1 SignalR Core](https://livetiming.formula1.com/signalrcore) (optional) | Live only | Real-time race data during active sessions |
298
+
299
+ ---
300
+
301
+ ## How It Works
302
+
303
+ Pitwall reads from F1's publicly available static timing archive — the same data that powers the official F1 app. After each session ends (~30 minutes), F1 publishes 33 data feeds per session including full car telemetry (speed, RPM, throttle, brake, gear, DRS at ~4Hz per car), GPS positions, tyre data, pit stops, and race control messages.
304
+
305
+ The telemetry tool (`get_telemetry`) correlates the timing stream with the car data stream to extract telemetry for a specific driver on a specific lap — something no other F1 MCP server does.
306
+
307
+ ### Architecture
308
+
309
+ ```
310
+ Claude ──MCP──> Pitwall ──HTTP──> livetiming.formula1.com/static/ (free)
311
+ ──HTTP──> api.jolpi.ca/ergast/f1/ (free)
312
+ ──lib──> FastF1 (optional, local)
313
+ ──WS───> SignalR Core (optional, live races)
314
+ ```
315
+
316
+ ### Running the Server
317
+
318
+ ```bash
319
+ python3 pitwall.py # MCP stdio (Claude Code / Claude Desktop)
320
+ python3 pitwall.py --http # MCP HTTP (remote / self-hosted)
321
+ python3 pitwall.py --http --port 3000
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Live Race Data
327
+
328
+ Pitwall includes a raw SignalR Core WebSocket client for real-time data during active F1 sessions. Most data is free — car telemetry and GPS require an F1 TV Pro or Premium subscription.
329
+
330
+ <details>
331
+ <summary><strong>What's free vs what needs F1 TV</strong></summary>
332
+
333
+ | Data | Free | F1 TV |
334
+ |------|------|-------|
335
+ | Race positions, gaps, lap times | Yes | Yes |
336
+ | Race control, flags, penalties | Yes | Yes |
337
+ | Weather, track status | Yes | Yes |
338
+ | Tyre compounds, stint info | Yes | Yes |
339
+ | Team radio URLs | Yes | Yes |
340
+ | **Car telemetry** (speed, RPM, throttle, brake) | No | **Yes** |
341
+ | **GPS positions** (X/Y/Z coordinates) | No | **Yes** |
342
+
343
+ > All data (including telemetry and GPS) becomes **free** in the static archive ~30 minutes after a session ends.
344
+
345
+ </details>
346
+
347
+ <details>
348
+ <summary><strong>Authentication setup</strong></summary>
349
+
350
+ ```bash
351
+ python3 auth_setup.py
352
+ ```
353
+
354
+ This opens a browser for F1 TV login. The token is saved locally:
355
+ - `<project_dir>/.f1token`
356
+ - `~/Library/Application Support/fastf1/f1auth.json` (macOS)
357
+
358
+ Token expires every ~4 days. Re-run to refresh. Never uploaded anywhere.
359
+
360
+ </details>
361
+
362
+ <details>
363
+ <summary><strong>Live client usage</strong></summary>
364
+
365
+ ```python
366
+ import asyncio
367
+ from signalr_client import F1LiveClient
368
+
369
+ async def main():
370
+ # Free mode — timing, weather, race control (no auth needed)
371
+ client = F1LiveClient(no_auth=True)
372
+
373
+ @client.on("TimingData")
374
+ def on_timing(data, timestamp):
375
+ for num, info in data.get("Lines", {}).items():
376
+ print(f"P{info.get('Position','?')} #{num} Gap: {info.get('GapToLeader','')}")
377
+
378
+ @client.on("RaceControlMessages")
379
+ def on_rc(data, timestamp):
380
+ for msg in data.get("Messages", {}).values():
381
+ print(f"[{msg.get('Flag', '')}] {msg.get('Message', '')}")
382
+
383
+ await client.connect()
384
+
385
+ asyncio.run(main())
386
+ ```
387
+
388
+ For full telemetry (speed, RPM, throttle, brake, GPS):
389
+
390
+ ```python
391
+ from auth_setup import load_token
392
+
393
+ client = F1LiveClient(no_auth=False, auth_token=load_token())
394
+
395
+ @client.on("CarData.z")
396
+ def on_telemetry(data, timestamp):
397
+ # Speed, RPM, throttle, brake, gear, DRS at ~4Hz per car
398
+ ...
399
+
400
+ @client.on("Position.z")
401
+ def on_position(data, timestamp):
402
+ # GPS X/Y/Z coordinates at ~4Hz per car
403
+ ...
404
+ ```
405
+
406
+ </details>
407
+
408
+ ---
409
+
410
+ ## Reference
411
+
412
+ ### Race Names
413
+
414
+ Race names are fuzzy-matched. All of these work:
415
+
416
+ ```
417
+ "china", "chinese", "shanghai" → Chinese Grand Prix
418
+ "australia", "melbourne", "aus" → Australian Grand Prix
419
+ "monaco", "monte carlo" → Monaco Grand Prix
420
+ "silverstone", "great britain", "british" → British Grand Prix
421
+ ```
422
+
423
+ ### Driver Codes
424
+
425
+ ```
426
+ VER = Verstappen HAM = Hamilton NOR = Norris LEC = Leclerc
427
+ ANT = Antonelli RUS = Russell PIA = Piastri BEA = Bearman
428
+ GAS = Gasly LAW = Lawson HAD = Hadjar SAI = Sainz
429
+ ALO = Alonso STR = Stroll OCO = Ocon BOT = Bottas
430
+ ALB = Albon HUL = Hulkenberg COL = Colapinto LIN = Lindblad
431
+ ```
432
+
433
+ ### Project Files
434
+
435
+ | File | Purpose |
436
+ |------|---------|
437
+ | `pitwall.py` | MCP server — 67 tools, auto-degrades to 14 without FastF1 |
438
+ | `signalr_client.py` | Raw SignalR Core WebSocket client for live race data |
439
+ | `decompressor.py` | Zlib decompression for CarData.z / Position.z |
440
+ | `merger.py` | Keyframe + delta state management for F1's incremental format |
441
+ | `topics.py` | All 20 SignalR topics with auth/compression metadata |
442
+ | `auth_setup.py` | F1 TV token setup — browser-based OAuth flow |
443
+
444
+ ---
445
+
446
+ ## Contributing
447
+
448
+ Found a bug? Want to add a tool? Contributions are welcome.
449
+
450
+ 1. Fork the repo
451
+ 2. Create a feature branch
452
+ 3. Make your changes
453
+ 4. Run the test suite: `python3 tests/pitwall_tool_validation.py`
454
+ 5. Open a pull request
455
+
456
+ ---
457
+
458
+ ## Credits
459
+
460
+ - [FastF1](https://github.com/theOehrly/Fast-F1) by @theOehrly — the gold standard F1 Python library
461
+ - [Jolpica-F1](https://github.com/jolpica/jolpica-f1) — the Ergast API successor
462
+ - [drivenrajat/f1](https://github.com/drivenrajat/f1) — inspiration for FastF1 tool patterns
463
+
464
+ ## Built by
465
+
466
+ **Darsh Joshi** — AI Engineer
467
+
468
+ [![LinkedIn](https://img.shields.io/badge/LinkedIn-darshjoshi-blue?logo=linkedin)](https://linkedin.com/in/darshjoshi)
469
+ [![GitHub](https://img.shields.io/badge/GitHub-darshjoshi-black?logo=github)](https://github.com/darshjoshi)
470
+ [![Email](https://img.shields.io/badge/Email-contact@darshjoshi.com-red?logo=gmail)](mailto:contact@darshjoshi.com)
471
+
472
+ ## License
473
+
474
+ MIT