o
    Ni                     @   s  d Z ddlmZmZmZ ddlmZ ddlmZ ddl	Z	ddl
mZ ddlmZ edd	d
Zejedgddgdgd eejd ZG dd deZG dd deZG dd deZG dd deZdd Zejdededddeddddddfd ed!ed"ee d#ee fd$d%Zejd&edd:d"ee fd'd(Zejd)edd*efd+d,Zejd-ee dd.d/ Zejd0edd1d2 Z e!d3krddl"Z"e# se$d4e  e$d5 e%d e$d6e  e"j&ed7d8d9 dS dS );z
FastAPI server for Italian vocabulary database.
Provides paginated access to 100k+ vocabulary entries.

Run with: uvicorn server:app --reload --port 5000
    )FastAPIQueryHTTPException)CORSMiddleware)	BaseModelN)Path)OptionalzItalian Vocabulary APIz1.0.0)titleversion*T)allow_originsallow_credentialsallow_methodsallow_headersz
italian.dbc                   @   s6   e Zd ZU eed< eed< eed< eed< eed< dS )	VocabItemiditalianenglishcategorynotesN)__name__
__module____qualname__int__annotations__str r   r   /var/www/html/it/server.pyr      s   
 r   c                   @   s:   e Zd ZU ee ed< eed< eed< eed< eed< dS )PaginatedResponseitemspageper_pagetotaltotal_pagesN)r   r   r   listr   r   r   r   r   r   r   r   $   s   
 r   c                   @   s   e Zd ZU eed< eed< dS )CategoryCountnamecountN)r   r   r   r   r   r   r   r   r   r   r%   +   s   
 r%   c                   @   s&   e Zd ZU eed< eeef ed< dS )StatsResponsetotal_entries
categoriesN)r   r   r   r   r   dictr   r   r   r   r   r(   /   s   
 r(   c                  C   s   t t} t j| _| S )zGet database connection.)sqlite3connectDB_PATHRowrow_factory)connr   r   r   get_db3   s   
r2   z
/api/vocab)response_model   )ge2      )r5   ler    r!   r   searchc                 C   s  | d | }|r|  nd}t }| }d}d}d}	d}
|rJd| d}|r9|d	| d
|	 d||||f n3|d| d
|	 d|||f n"|r]|d| d
|
 d|||f n|d| d
|
 d||f | }dd |D }|rd| d}|r|d| d||f n!|d| d|f n|r|d| |f n|d|  | d }|  || |||| d | dS )a	  
    Get paginated vocabulary entries.

    - **page**: Page number (default: 1)
    - **per_page**: Items per page (default: 50, max: 200)
    - **category**: Filter by category (optional)
    - **search**: Search term (optional, searches italian and english)
    r4   Nz1v.italian GLOB '[a-z]*' AND length(v.italian) > 1-italian GLOB '[a-z]*' AND length(italian) > 1z)ORDER BY (v.id * 2654435761) % 2147483647z'ORDER BY (id * 2654435761) % 2147483647"z"*z
                SELECT v.id, v.italian, v.english, v.category, v.notes
                FROM vocabulary v
                JOIN vocabulary_fts fts ON v.id = fts.rowid
                WHERE vocabulary_fts MATCH ? AND v.category = ? AND z
                z.
                LIMIT ? OFFSET ?
            z
                SELECT v.id, v.italian, v.english, v.category, v.notes
                FROM vocabulary v
                JOIN vocabulary_fts fts ON v.id = fts.rowid
                WHERE vocabulary_fts MATCH ? AND z
                SELECT id, italian, english, category, notes
                FROM vocabulary
                WHERE category = ? AND zt
                SELECT id, italian, english, category, notes
                FROM vocabulary
                WHERE c                 S   s   g | ]}t |qS r   )r+   .0rowr   r   r   
<listcomp>~   s    zget_vocab.<locals>.<listcomp>z
                SELECT COUNT(*) FROM vocabulary v
                JOIN vocabulary_fts fts ON v.id = fts.rowid
                WHERE vocabulary_fts MATCH ? AND v.category = ? AND z
            z
                SELECT COUNT(*) FROM vocabulary v
                JOIN vocabulary_fts fts ON v.id = fts.rowid
                WHERE vocabulary_fts MATCH ? AND z7SELECT COUNT(*) FROM vocabulary WHERE category = ? AND z&SELECT COUNT(*) FROM vocabulary WHERE r   )r   r    r!   r"   r#   )stripr2   cursorexecutefetchallfetchoneclose)r    r!   r   r9   offsetr1   curbase_filterbase_filter_no_aliasorder_clauseorder_clause_no_aliassearch_termrowsr   r"   r   r   r   	get_vocab9   s   
		rN   z/api/vocab/randomc                 C   sh   t  }| }d}| r|d| d| f n	|d| d | }|  |r.t|S tddd)z?Get a random vocabulary entry, optionally filtered by category.r:   zy
            SELECT id, italian, english, category, notes
            FROM vocabulary
            WHERE category = ? AND z;
            ORDER BY RANDOM()
            LIMIT 1
        zh
            SELECT id, italian, english, category, notes
            FROM vocabulary
            WHERE   zNo entries foundstatus_codedetailr2   rA   rB   rD   rE   r+   r   )r   r1   rG   rH   r>   r   r   r   
get_random   s"   
rT   z/api/vocab/{id}r   c                 C   sD   t  }| }|d| f | }|  |rt|S tddd)z&Get a specific vocabulary entry by ID.zISELECT id, italian, english, category, notes FROM vocabulary WHERE id = ?rO   z	Not foundrP   rS   )r   r1   rG   r>   r   r   r   get_vocab_by_id   s   rU   z/api/categoriesc                  C   s6   t  } |  }|d | }|   dd |D S )z#Get list of categories with counts.~
        SELECT category, COUNT(*) as count
        FROM vocabulary
        GROUP BY category
        ORDER BY count DESC
    c                 S   s   g | ]}|d  |d dqS )r   r'   )r&   r'   r   r<   r   r   r   r?      s    z"get_categories.<locals>.<listcomp>)r2   rA   rB   rC   rE   )r1   rG   rM   r   r   r   get_categories   s   
rW   z
/api/statsc                  C   sR   t  } |  }|d | d }|d dd | D }|   ||dS )zGet database statistics.zSELECT COUNT(*) FROM vocabularyr   rV   c                 S   s   i | ]	}|d  |d qS )r   r'   r   r<   r   r   r   
<dictcomp>   s    zget_stats.<locals>.<dictcomp>)r)   r*   )r2   rA   rB   rD   rC   rE   )r1   rG   r"   r*   r   r   r   	get_stats   s   

rY   __main__zDatabase not found at zRun: python build_vocab_db.pyzStarting server with database: z0.0.0.0i  )hostport)N)'__doc__fastapir   r   r   fastapi.middleware.corsr   pydanticr   r,   pathlibr   typingr   appadd_middleware__file__parentr.   r   r   r%   r(   r2   getr   r   rN   rT   rU   r$   rW   rY   r   uvicornexistsprintexitrunr   r   r   r   <module>   sh   
f 

