| import os |
| import sys |
| import warnings |
| from dotenv import load_dotenv |
| from appwrite.client import Client |
| from appwrite.services.databases import Databases |
|
|
| |
| warnings.filterwarnings("ignore", category=DeprecationWarning) |
|
|
| |
| load_dotenv() |
|
|
| |
| APPWRITE_ENDPOINT = os.getenv("APPWRITE_ENDPOINT", "https://cloud.appwrite.io/v1") |
| APPWRITE_PROJECT_ID = os.getenv("APPWRITE_PROJECT_ID") |
| APPWRITE_API_KEY = os.getenv("APPWRITE_API_KEY") |
| APPWRITE_DATABASE_ID = os.getenv("APPWRITE_DATABASE_ID") |
| RESEARCH_COLLECTION_ID = os.getenv("APPWRITE_RESEARCH_COLLECTION_ID", "69845c19002c864d4d3f") |
|
|
| if not all([APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, APPWRITE_API_KEY, APPWRITE_DATABASE_ID]): |
| print("β Missing environment variables. Please check .env file.") |
| sys.exit(1) |
|
|
| |
| client = Client() |
| client.set_endpoint(APPWRITE_ENDPOINT) |
| client.set_project(APPWRITE_PROJECT_ID) |
| client.set_key(APPWRITE_API_KEY) |
|
|
| databases = Databases(client) |
|
|
| def init_research_schema(): |
| print(f"π¬ Initializing Schema for Collection: {RESEARCH_COLLECTION_ID}") |
| |
| |
| try: |
| databases.get_collection(APPWRITE_DATABASE_ID, RESEARCH_COLLECTION_ID) |
| print("β
Collection exists.") |
| except Exception as e: |
| print(f"β Collection not found: {e}") |
| return |
|
|
| |
| required_attributes = [ |
| {"key": "paper_id", "type": "string", "size": 255, "required": True}, |
| {"key": "title", "type": "string", "size": 500, "required": True}, |
| {"key": "summary", "type": "string", "size": 5000, "required": False}, |
| {"key": "authors", "type": "string", "size": 5000, "required": False}, |
| {"key": "published_at", "type": "datetime", "required": True}, |
| {"key": "pdf_url", "type": "url", "required": True}, |
| {"key": "category", "type": "string", "size": 255, "required": True}, |
| {"key": "sub_category", "type": "string", "size": 255, "required": False}, |
| {"key": "original_category", "type": "string", "size": 255, "required": True}, |
| {"key": "likes", "type": "integer", "required": False, "default": 0}, |
| {"key": "dislike", "type": "integer", "required": False, "default": 0}, |
| {"key": "views", "type": "integer", "required": False, "default": 0}, |
| ] |
|
|
| |
| import time |
| |
| try: |
| attrs = databases.list_attributes(APPWRITE_DATABASE_ID, RESEARCH_COLLECTION_ID) |
| existing_attributes = {attr['key']: attr for attr in attrs['attributes']} |
| existing_keys = list(existing_attributes.keys()) |
| print(f"Existing Attributes: {existing_keys}") |
| |
| for attr in required_attributes: |
| key = attr['key'] |
| if key not in existing_keys: |
| print(f"βοΈ Creating attribute: {key}...") |
| try: |
| if attr['type'] == "string": |
| databases.create_string_attribute( |
| database_id=APPWRITE_DATABASE_ID, |
| collection_id=RESEARCH_COLLECTION_ID, |
| key=key, |
| size=attr['size'], |
| required=attr['required'], |
| default=attr.get('default') |
| ) |
| elif attr['type'] == "datetime": |
| databases.create_datetime_attribute( |
| database_id=APPWRITE_DATABASE_ID, |
| collection_id=RESEARCH_COLLECTION_ID, |
| key=key, |
| required=attr['required'], |
| default=attr.get('default') |
| ) |
| elif attr['type'] == "url": |
| databases.create_url_attribute( |
| database_id=APPWRITE_DATABASE_ID, |
| collection_id=RESEARCH_COLLECTION_ID, |
| key=key, |
| required=attr['required'], |
| default=attr.get('default') |
| ) |
| elif attr['type'] == "integer": |
| databases.create_integer_attribute( |
| database_id=APPWRITE_DATABASE_ID, |
| collection_id=RESEARCH_COLLECTION_ID, |
| key=key, |
| required=attr['required'], |
| min=0, |
| max=None, |
| default=attr.get('default') |
| ) |
| print(f" β
Request sent for: {key}") |
| except Exception as attr_error: |
| print(f" β Failed to create {key}: {attr_error}") |
| else: |
| print(f" πΉ Exists: {key}") |
| |
| |
| print("\nβ³ Waiting for attributes to become 'available'...") |
| pending_attrs = [attr['key'] for attr in required_attributes] |
| max_retries = 30 |
| |
| for key in pending_attrs: |
| for attempt in range(max_retries): |
| try: |
| |
| |
| curr_attrs = databases.list_attributes(APPWRITE_DATABASE_ID, RESEARCH_COLLECTION_ID)['attributes'] |
| target = next((a for a in curr_attrs if a['key'] == key), None) |
| |
| if target and target['status'] == 'available': |
| print(f" β
{key} is available.") |
| break |
| elif target and target['status'] == 'failed': |
| print(f" β {key} creation FAILED in Appwrite.") |
| break |
| else: |
| if attempt % 5 == 0: |
| print(f" ... waiting for {key} (attempt {attempt+1}/{max_retries})") |
| time.sleep(2) |
| except Exception as e: |
| print(f"Error checking status for {key}: {e}") |
| time.sleep(2) |
| else: |
| print(f" β οΈ Timeout waiting for {key} to be available.") |
|
|
| |
| |
| print("\nβοΈ Checking/Creating index on paper_id...") |
| try: |
| databases.create_index( |
| database_id=APPWRITE_DATABASE_ID, |
| collection_id=RESEARCH_COLLECTION_ID, |
| key="unique_paper_id", |
| type="unique", |
| attributes=["paper_id"] |
| ) |
| print(" β
Index created.") |
| except Exception as e: |
| |
| if "already exists" in str(e) or "409" in str(e): |
| print(" πΉ Index already exists.") |
| elif "attribute not found" in str(e).lower() or "processing" in str(e).lower(): |
| print(f" β Index creation failed: Attributes still processing or missing. ({e})") |
| else: |
| print(f" β οΈ Could not create index: {e}") |
|
|
| except Exception as e: |
| print(f"β Error during schema initialization: {e}") |
|
|
| if __name__ == "__main__": |
| init_research_schema() |
|
|