Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| from typing import Dict, Any | |
| # Workaround for Python 3.10: Add NotRequired to typing module | |
| if sys.version_info < (3, 11): | |
| try: | |
| from typing_extensions import NotRequired | |
| import typing | |
| if not hasattr(typing, 'NotRequired'): | |
| typing.NotRequired = NotRequired | |
| except ImportError: | |
| pass | |
| # Try to import MPRester, handle case where key is missing/invalid gracefully | |
| try: | |
| from mp_api.client import MPRester | |
| except ImportError: | |
| MPRester = None | |
| class MaterialsProjectAdapter: | |
| def __init__(self, api_key: str = None): | |
| self.api_key = api_key | |
| self.has_key = api_key is not None and len(api_key) > 10 and MPRester is not None | |
| def get_material_properties(self, formula: str) -> Dict[str, Any]: | |
| print(f"CONTACTING MATERIALS PROJECT: {formula}...") | |
| if self.has_key: | |
| try: | |
| with MPRester(self.api_key) as mpr: | |
| docs = mpr.materials.summary.search( | |
| formula=[formula], | |
| fields=["band_gap", "volume", "formation_energy_per_atom"] | |
| ) | |
| if docs: | |
| best_match = min(docs, key=lambda x: x.formation_energy_per_atom) | |
| return { | |
| "source": "Materials Project (Real Data)", | |
| "band_gap": float(best_match.band_gap), | |
| "volume": float(best_match.volume), | |
| "is_estimated": False | |
| } | |
| except Exception as e: | |
| print(f"❌ API ERROR: {str(e)}. Switching to fallback.") | |
| # Fallback if no key or API fails | |
| return self._generate_fallback(formula) | |
| def _generate_fallback(self, formula: str) -> Dict[str, Any]: | |
| return { | |
| "source": "Theoretical Estimation (Fallback)", | |
| "band_gap": 2.0, | |
| "volume": 200.0, | |
| "is_estimated": True | |
| } |