Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| from io import BytesIO | |
| def convert_file(input_file, conversion_type): | |
| # Check if a file was uploaded | |
| if input_file is None: | |
| raise ValueError("Please upload a file.") | |
| # Determine if input_file is a file-like object or a file path string | |
| try: | |
| # Try reading from file-like object | |
| file_bytes = input_file.read() | |
| file_name = input_file.name | |
| except AttributeError: | |
| # If there's an AttributeError, treat input_file as a file path | |
| file_name = input_file | |
| with open(file_name, "rb") as f: | |
| file_bytes = f.read() | |
| file_extension = file_name.lower().split('.')[-1] | |
| df = None | |
| output_file = None | |
| converted_format = None | |
| # Conversion: CSV to Parquet | |
| if conversion_type == "CSV to Parquet": | |
| if file_extension != "csv": | |
| raise ValueError("For CSV to Parquet conversion, please upload a CSV file.") | |
| df = pd.read_csv(BytesIO(file_bytes)) | |
| output_file = "output.parquet" | |
| df.to_parquet(output_file, index=False) | |
| converted_format = "Parquet" | |
| # Conversion: Parquet to CSV | |
| elif conversion_type == "Parquet to CSV": | |
| if file_extension != "parquet": | |
| raise ValueError("For Parquet to CSV conversion, please upload a Parquet file.") | |
| df = pd.read_parquet(BytesIO(file_bytes)) | |
| output_file = "output.csv" | |
| df.to_csv(output_file, index=False) | |
| converted_format = "CSV" | |
| else: | |
| raise ValueError("Invalid conversion type selected.") | |
| # Generate a preview of the top 10 rows | |
| preview = df.head(10).to_string(index=False) | |
| info_message = ( | |
| f"Input file: {file_name}\n" | |
| f"Converted file format: {converted_format}\n" | |
| f"Total rows: {len(df)}\n" | |
| f"Total columns: {len(df.columns)}\n\n" | |
| f"Preview (Top 10 Rows):\n{preview}" | |
| ) | |
| return output_file, info_message | |
| # Enhanced custom CSS for a more visually appealing interface | |
| custom_css = """ | |
| body { | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| font-family: 'Poppins', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| } | |
| .gradio-container { | |
| max-width: 950px; | |
| margin: 40px auto; | |
| padding: 30px; | |
| background-color: #ffffff; | |
| border-radius: 16px; | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.1); | |
| } | |
| h1 { | |
| color: #3a4149; | |
| font-size: 2.5rem; | |
| text-align: center; | |
| margin-bottom: 5px; | |
| font-weight: 600; | |
| } | |
| h2 { | |
| color: #5a6570; | |
| font-size: 1.2rem; | |
| text-align: center; | |
| margin-bottom: 25px; | |
| font-weight: 400; | |
| } | |
| .header-icon { | |
| font-size: 3rem; | |
| text-align: center; | |
| margin-bottom: 10px; | |
| color: #4285f4; | |
| } | |
| .instruction-box { | |
| background-color: #f8f9fa; | |
| border-left: 4px solid #4285f4; | |
| padding: 15px; | |
| margin-bottom: 25px; | |
| border-radius: 6px; | |
| } | |
| .instruction-step { | |
| margin: 8px 0; | |
| padding-left: 10px; | |
| } | |
| .file-box { | |
| border: 2px dashed #ddd; | |
| border-radius: 12px; | |
| padding: 20px; | |
| transition: all 0.3s ease; | |
| } | |
| .file-box:hover { | |
| border-color: #4285f4; | |
| box-shadow: 0 5px 15px rgba(66, 133, 244, 0.15); | |
| } | |
| .conversion-radio label { | |
| padding: 10px 15px; | |
| margin: 5px; | |
| border-radius: 8px; | |
| border: 1px solid #eaeaea; | |
| transition: all 0.2s ease; | |
| } | |
| .conversion-radio input:checked + label { | |
| background-color: #e8f0fe; | |
| border-color: #4285f4; | |
| color: #4285f4; | |
| } | |
| .convert-button { | |
| background: linear-gradient(to right, #4285f4, #34a853) !important; | |
| color: white !important; | |
| border: none !important; | |
| padding: 12px 25px !important; | |
| font-size: 16px !important; | |
| font-weight: 500 !important; | |
| border-radius: 30px !important; | |
| cursor: pointer; | |
| margin: 20px auto !important; | |
| display: block !important; | |
| box-shadow: 0 4px 12px rgba(66, 133, 244, 0.25) !important; | |
| } | |
| .convert-button:hover { | |
| box-shadow: 0 6px 16px rgba(66, 133, 244, 0.4) !important; | |
| transform: translateY(-2px); | |
| } | |
| .footer { | |
| text-align: center; | |
| margin-top: 30px; | |
| color: #70757a; | |
| font-size: 0.9rem; | |
| } | |
| .preview-box { | |
| background-color: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 15px; | |
| font-family: monospace; | |
| white-space: pre-wrap; | |
| max-height: 400px; | |
| overflow-y: auto; | |
| } | |
| .info-tag { | |
| display: inline-block; | |
| background-color: #e8f0fe; | |
| color: #4285f4; | |
| padding: 4px 10px; | |
| border-radius: 20px; | |
| font-size: 0.85rem; | |
| margin-right: 8px; | |
| margin-bottom: 8px; | |
| } | |
| .divider { | |
| height: 1px; | |
| background: linear-gradient(to right, transparent, #ddd, transparent); | |
| margin: 25px 0; | |
| } | |
| """ | |
| with gr.Blocks(css=custom_css, title="DataFormat Converter") as demo: | |
| gr.HTML('<div class="header-icon">📊</div>') | |
| gr.Markdown("# DataFormat Converter") | |
| gr.Markdown("## Seamlessly convert between CSV and Parquet formats with just a few clicks") | |
| gr.HTML('<div class="divider"></div>') | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.HTML(""" | |
| <div class="instruction-box"> | |
| <h3>How It Works</h3> | |
| <div class="instruction-step">1. Upload your CSV or Parquet file</div> | |
| <div class="instruction-step">2. Select the conversion direction</div> | |
| <div class="instruction-step">3. Click "Convert" and download your transformed file</div> | |
| </div> | |
| <div class="info-section"> | |
| <div class="info-tag">Fast Conversion</div> | |
| <div class="info-tag">Data Preview</div> | |
| <div class="info-tag">No Size Limits</div> | |
| <div class="info-tag">Maintains Structure</div> | |
| </div> | |
| """) | |
| gr.HTML(""" | |
| <div style="margin-top: 25px;"> | |
| <h3>Why Convert?</h3> | |
| <p>Parquet files offer significant advantages for data storage and analysis:</p> | |
| <ul> | |
| <li>Smaller file size (up to 87% reduction)</li> | |
| <li>Faster query performance</li> | |
| <li>Column-oriented storage</li> | |
| <li>Better compression</li> | |
| </ul> | |
| <p>CSV files are useful for:</p> | |
| <ul> | |
| <li>Universal compatibility</li> | |
| <li>Human readability</li> | |
| <li>Simple integration with many tools</li> | |
| </ul> | |
| </div> | |
| """) | |
| with gr.Column(): | |
| # Replace gr.Box with a div using gr.HTML for the file-box styling | |
| gr.HTML('<div class="file-box">') | |
| input_file = gr.File(label="Upload Your File") | |
| conversion_type = gr.Radio( | |
| choices=["CSV to Parquet", "Parquet to CSV"], | |
| label="Select Conversion Type", | |
| value="CSV to Parquet", | |
| elem_classes=["conversion-radio"] | |
| ) | |
| convert_button = gr.Button("Convert Now", elem_classes=["convert-button"]) | |
| gr.HTML('</div>') # Close the file-box div | |
| with gr.Accordion("Conversion Results", open=False): | |
| output_file = gr.File(label="Download Converted File") | |
| with gr.Accordion("Data Preview", open=True): | |
| preview = gr.Textbox( | |
| label="File Information and Preview", | |
| lines=15, | |
| elem_classes=["preview-box"] | |
| ) | |
| gr.HTML('<div class="divider"></div>') | |
| gr.HTML(""" | |
| <div class="footer"> | |
| <p>DataFormat Converter © 2025 | Built with Gradio | An efficient tool for data professionals</p> | |
| </div> | |
| """) | |
| convert_button.click( | |
| fn=convert_file, | |
| inputs=[input_file, conversion_type], | |
| outputs=[output_file, preview] | |
| ) | |
| demo.launch() |