Spaces:
Running
Running
import { ProviderInfo, ModelData } from "../types/heatmap"; | |
interface AuthorData { | |
author: string; | |
fullName: string; | |
avatarUrl: string | null; | |
isVerified: boolean; | |
isEnterprise: boolean; | |
numModels: number; | |
numSpaces: number; | |
numDatasets: number; | |
numFollowers: number; | |
numUsers: number; | |
} | |
const createDefaultAuthorData = (author: string): AuthorData => ({ | |
author, | |
fullName: author, | |
avatarUrl: null, | |
isVerified: false, | |
isEnterprise: false, | |
numModels: 0, | |
numSpaces: 0, | |
numDatasets: 0, | |
numFollowers: 0, | |
numUsers: 0, | |
}); | |
const transformApiData = (author: string, data: any, isOrganization: boolean): AuthorData => ({ | |
author, | |
fullName: data.fullname || author, | |
avatarUrl: data.avatarUrl || null, | |
isVerified: data.isVerified || false, | |
isEnterprise: isOrganization ? (data.isEnterprise || false) : false, | |
numModels: data.numModels || 0, | |
numSpaces: data.numSpaces || 0, | |
numDatasets: data.numDatasets || 0, | |
numFollowers: data.numFollowers || 0, | |
numUsers: isOrganization ? (data.numUsers || 0) : 0, | |
}); | |
async function fetchSingleAuthorData(author: string): Promise<AuthorData> { | |
try { | |
// Try organizations API first | |
const orgResponse = await fetch(`https://huggingface.co/api/organizations/${author}/overview`); | |
if (orgResponse.ok) { | |
const data = await orgResponse.json(); | |
return transformApiData(author, data, true); | |
} | |
// Fallback to users API | |
const userResponse = await fetch(`https://huggingface.co/api/users/${author}/overview`); | |
if (userResponse.ok) { | |
const data = await userResponse.json(); | |
return transformApiData(author, data, false); | |
} | |
throw new Error('Neither organization nor user API returned valid data'); | |
} catch (error) { | |
console.error(`Error fetching data for ${author}:`, error); | |
return createDefaultAuthorData(author); | |
} | |
} | |
export async function fetchOrganizationData(authors: string[]) { | |
try { | |
const authorsData = await Promise.all( | |
authors.map(author => fetchSingleAuthorData(author)) | |
); | |
const primaryAuthor = authorsData[0]; | |
const aggregatedStats = authorsData.reduce( | |
(acc, authorData) => ({ | |
numModels: acc.numModels + authorData.numModels, | |
numSpaces: acc.numSpaces + authorData.numSpaces, | |
numDatasets: acc.numDatasets + authorData.numDatasets, | |
numFollowers: acc.numFollowers + authorData.numFollowers, | |
numUsers: acc.numUsers + authorData.numUsers, | |
}), | |
{ numModels: 0, numSpaces: 0, numDatasets: 0, numFollowers: 0, numUsers: 0 } | |
); | |
return { | |
fullName: primaryAuthor.fullName, | |
avatarUrl: primaryAuthor.avatarUrl, | |
isVerified: primaryAuthor.isVerified, | |
isEnterprise: primaryAuthor.isEnterprise, | |
authorsData, // Include all authors data for multi-logo display | |
...aggregatedStats, | |
}; | |
} catch (error) { | |
console.error(`Error fetching organization data for authors:`, error); | |
const primaryAuthor = authors[0]; | |
const defaultAuthorData = createDefaultAuthorData(primaryAuthor); | |
return { | |
fullName: primaryAuthor, | |
avatarUrl: null, | |
isVerified: false, | |
isEnterprise: false, | |
authorsData: [defaultAuthorData], | |
numModels: 0, | |
numSpaces: 0, | |
numDatasets: 0, | |
numFollowers: 0, | |
numUsers: 0, | |
}; | |
} | |
} | |
export async function fetchAllProvidersData(providers: ProviderInfo[]): Promise<ProviderInfo[]> { | |
return Promise.all( | |
providers.map(async (providerInfo) => { | |
const orgData = await fetchOrganizationData(providerInfo.authors); | |
return { | |
...providerInfo, | |
...orgData | |
}; | |
}) | |
); | |
} | |
async function fetchAuthorEntityData(author: string, entityType: string): Promise<ModelData[]> { | |
const response = await fetch( | |
`https://huggingface.co/api/${entityType}?author=${author}&sort=createdAt&direction=-1` | |
); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
const data = await response.json(); | |
return data.map((item: any): ModelData => ({ | |
createdAt: item.createdAt, | |
id: item.id, | |
})); | |
} | |
export async function fetchAuthorData(author: string): Promise<ModelData[]> { | |
const entityTypes = ["models", "datasets", "spaces"] as const; | |
try { | |
const allData = await Promise.all( | |
entityTypes.map(type => fetchAuthorEntityData(author, type)) | |
); | |
return allData.flat(); | |
} catch (error) { | |
console.error(`Error fetching data for author ${author}:`, error); | |
return []; | |
} | |
} | |
export async function fetchAllAuthorsData(authors: string[]): Promise<ModelData[]> { | |
try { | |
const allData = await Promise.all( | |
authors.map(author => fetchAuthorData(author)) | |
); | |
return allData.flat(); | |
} catch (error) { | |
console.error("Error fetching data for all authors:", error); | |
return []; | |
} | |
} |