mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
- Complete platform specification and architecture - MVP concept and business model - Technical implementation plans and roadmaps - Financial projections and funding strategy - Brand identity and marketing materials - Mathematical models for resource matching - Competitive analysis and market research - Go-based core models and algorithms Turash guides businesses to optimal resource exchanges, navigating the complex landscape of industrial symbiosis and providing direction to sustainable profitability.
371 lines
10 KiB
Go
371 lines
10 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// EUFundingAPI represents the EU Funding & Tenders Portal API client
|
|
type EUFundingAPI struct {
|
|
BaseURL string
|
|
SearchAPIKey string
|
|
FAQAPIKey string
|
|
PersonAPIKey string
|
|
Client *http.Client
|
|
}
|
|
|
|
// NewEUFundingAPI creates a new API client instance
|
|
func NewEUFundingAPI() *EUFundingAPI {
|
|
return &EUFundingAPI{
|
|
BaseURL: "https://api.tech.ec.europa.eu/search-api/prod/rest",
|
|
SearchAPIKey: "SEDIA",
|
|
FAQAPIKey: "SEDIA_FAQ",
|
|
PersonAPIKey: "SEDIA_PERSON",
|
|
Client: &http.Client{
|
|
Timeout: 30 * time.Second,
|
|
},
|
|
}
|
|
}
|
|
|
|
// SearchQuery represents the Elasticsearch query structure
|
|
type SearchQuery struct {
|
|
Bool struct {
|
|
Must []interface{} `json:"must"`
|
|
} `json:"bool"`
|
|
}
|
|
|
|
// APIResponse represents the standard API response
|
|
type APIResponse struct {
|
|
Results []map[string]interface{} `json:"results"`
|
|
Total int `json:"total"`
|
|
}
|
|
|
|
// makeRequest performs HTTP requests to the API
|
|
func (api *EUFundingAPI) makeRequest(endpoint string, method string, data interface{}) (*APIResponse, error) {
|
|
var body io.Reader
|
|
if data != nil && method == "POST" {
|
|
jsonData, err := json.Marshal(data)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to marshal request data: %v", err)
|
|
}
|
|
body = bytes.NewBuffer(jsonData)
|
|
}
|
|
|
|
req, err := http.NewRequest(method, endpoint, body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create request: %v", err)
|
|
}
|
|
|
|
req.Header.Set("User-Agent", "EU-Funding-API-Client-Go/1.0")
|
|
req.Header.Set("Accept", "application/json")
|
|
if body != nil {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
|
|
resp, err := api.Client.Do(req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("request failed: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("API returned status %d", resp.StatusCode)
|
|
}
|
|
|
|
var response APIResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
|
return nil, fmt.Errorf("failed to decode response: %v", err)
|
|
}
|
|
|
|
return &response, nil
|
|
}
|
|
|
|
// SearchGrantsTenders searches for grants and tenders
|
|
func (api *EUFundingAPI) SearchGrantsTenders(query *SearchQuery) (*APIResponse, error) {
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
|
|
|
|
if query == nil {
|
|
// Default query to get all grants and tenders
|
|
query = &SearchQuery{}
|
|
query.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"0", "1", "2", "8"}, // All types
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"status": {"31094501", "31094502", "31094503"}, // All statuses
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
return api.makeRequest(endpoint, "POST", query)
|
|
}
|
|
|
|
// GetTopicDetails gets detailed information about a specific topic
|
|
func (api *EUFundingAPI) GetTopicDetails(topicIdentifier string) (*APIResponse, error) {
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=\"%s\"", api.BaseURL, api.SearchAPIKey, topicIdentifier)
|
|
return api.makeRequest(endpoint, "GET", nil)
|
|
}
|
|
|
|
// SearchGrantUpdates searches for grant updates
|
|
func (api *EUFundingAPI) SearchGrantUpdates(frameworkProgramme string) (*APIResponse, error) {
|
|
query := &SearchQuery{}
|
|
query.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"6"}, // Grant updates
|
|
},
|
|
},
|
|
}
|
|
|
|
if frameworkProgramme != "" {
|
|
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"frameworkProgramme": {frameworkProgramme},
|
|
},
|
|
})
|
|
}
|
|
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
|
|
return api.makeRequest(endpoint, "POST", query)
|
|
}
|
|
|
|
// SearchFAQs searches FAQs
|
|
func (api *EUFundingAPI) SearchFAQs(programme string) (*APIResponse, error) {
|
|
query := &SearchQuery{}
|
|
query.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"0", "1"}, // FAQ types
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"status": {"0", "1"}, // All statuses
|
|
},
|
|
},
|
|
}
|
|
|
|
if programme != "" {
|
|
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
|
|
"term": map[string]string{
|
|
"programme": programme,
|
|
},
|
|
})
|
|
}
|
|
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.FAQAPIKey)
|
|
return api.makeRequest(endpoint, "POST", query)
|
|
}
|
|
|
|
// GetOrganizationData gets organization public data
|
|
func (api *EUFundingAPI) GetOrganizationData(picCode string) (*APIResponse, error) {
|
|
endpoint := fmt.Sprintf("%s/document/%s?apiKey=%s", api.BaseURL, picCode, api.PersonAPIKey)
|
|
return api.makeRequest(endpoint, "GET", nil)
|
|
}
|
|
|
|
// SearchPartners searches for partners in a specific topic
|
|
func (api *EUFundingAPI) SearchPartners(topic string) (*APIResponse, error) {
|
|
query := &SearchQuery{}
|
|
query.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"topics": {topic},
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"ORGANISATION", "PERSON"},
|
|
},
|
|
},
|
|
}
|
|
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
|
|
return api.makeRequest(endpoint, "POST", query)
|
|
}
|
|
|
|
// SearchProjects searches for EU funded projects
|
|
func (api *EUFundingAPI) SearchProjects(programmeID, missionGroup string) (*APIResponse, error) {
|
|
query := &SearchQuery{}
|
|
|
|
if programmeID != "" {
|
|
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"programId": {programmeID},
|
|
},
|
|
})
|
|
}
|
|
|
|
if missionGroup != "" {
|
|
query.Bool.Must = append(query.Bool.Must, map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"missionGroup": {missionGroup},
|
|
},
|
|
})
|
|
}
|
|
|
|
endpoint := fmt.Sprintf("%s/search?apiKey=%s&text=***", api.BaseURL, api.SearchAPIKey)
|
|
return api.makeRequest(endpoint, "POST", query)
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("EU Funding & Tenders Portal API Client (Go)")
|
|
fmt.Println("=" + strings.Repeat("=", 50))
|
|
|
|
api := NewEUFundingAPI()
|
|
|
|
// Example 1: Search for EIC Accelerator opportunities
|
|
fmt.Println("\n1. Searching for EIC Accelerator opportunities...")
|
|
|
|
eicQuery := &SearchQuery{}
|
|
eicQuery.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"1", "2", "8"}, // Grants
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"status": {"31094501", "31094502", "31094503"}, // All statuses
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"term": map[string]string{
|
|
"callIdentifier": "HORIZON-EIC-2026-ACCELERATOR-01",
|
|
},
|
|
},
|
|
}
|
|
|
|
results, err := api.SearchGrantsTenders(eicQuery)
|
|
if err != nil {
|
|
log.Printf("Error searching grants: %v", err)
|
|
} else {
|
|
fmt.Printf("Found %d EIC Accelerator opportunities\n", len(results.Results))
|
|
for i, result := range results.Results {
|
|
if i >= 3 { // Show first 3
|
|
break
|
|
}
|
|
if title, ok := result["title"].(string); ok {
|
|
fmt.Printf("- %s\n", title)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Example 2: Get topic details for EIC Accelerator
|
|
fmt.Println("\n2. Getting EIC Accelerator topic details...")
|
|
topicDetails, err := api.GetTopicDetails("HORIZON-EIC-2026-ACCELERATOR-01")
|
|
if err != nil {
|
|
log.Printf("Error getting topic details: %v", err)
|
|
} else {
|
|
fmt.Println("Topic details retrieved successfully")
|
|
if len(topicDetails.Results) > 0 {
|
|
topic := topicDetails.Results[0]
|
|
if title, ok := topic["title"].(string); ok {
|
|
fmt.Printf("Title: %s\n", title)
|
|
}
|
|
if status, ok := topic["status"].(string); ok {
|
|
fmt.Printf("Status: %s\n", status)
|
|
}
|
|
if deadline, ok := topic["deadline"].(string); ok {
|
|
fmt.Printf("Deadline: %s\n", deadline)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Example 3: Search for grant updates
|
|
fmt.Println("\n3. Searching for recent grant updates...")
|
|
updates, err := api.SearchGrantUpdates("43108390") // Horizon Europe
|
|
if err != nil {
|
|
log.Printf("Error searching updates: %v", err)
|
|
} else {
|
|
fmt.Printf("Found %d grant updates\n", len(updates.Results))
|
|
}
|
|
|
|
// Example 4: Search FAQs
|
|
fmt.Println("\n4. Searching for FAQs...")
|
|
faqs, err := api.SearchFAQs("")
|
|
if err != nil {
|
|
log.Printf("Error searching FAQs: %v", err)
|
|
} else {
|
|
fmt.Printf("Found %d FAQs\n", len(faqs.Results))
|
|
}
|
|
|
|
fmt.Println("\nGo API client demonstration completed!")
|
|
}
|
|
|
|
// EICAcceleratorMonitor monitors EIC Accelerator opportunities
|
|
func EICAcceleratorMonitor() {
|
|
fmt.Println("EIC Accelerator Monitor")
|
|
fmt.Println("=" + strings.Repeat("=", 30))
|
|
|
|
api := NewEUFundingAPI()
|
|
|
|
// Query for EIC Accelerator opportunities
|
|
query := &SearchQuery{}
|
|
query.Bool.Must = []interface{}{
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"type": {"1", "2", "8"},
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"terms": map[string][]string{
|
|
"status": {"31094501", "31094502"}, // Open and forthcoming
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"term": map[string]string{
|
|
"frameworkProgramme": "43108390", // Horizon Europe
|
|
},
|
|
},
|
|
map[string]interface{}{
|
|
"query_string": map[string]interface{}{
|
|
"query": "EIC Accelerator",
|
|
"default_field": "title",
|
|
},
|
|
},
|
|
}
|
|
|
|
results, err := api.SearchGrantsTenders(query)
|
|
if err != nil {
|
|
log.Printf("Error monitoring EIC Accelerator: %v", err)
|
|
return
|
|
}
|
|
|
|
if results != nil && len(results.Results) > 0 {
|
|
fmt.Printf("Found %d EIC Accelerator opportunities:\n", len(results.Results))
|
|
|
|
for _, opp := range results.Results {
|
|
title := getStringValue(opp, "title")
|
|
identifier := getStringValue(opp, "identifier")
|
|
status := getStringValue(opp, "status")
|
|
deadline := getStringValue(opp, "deadline")
|
|
|
|
fmt.Printf("\n📋 %s\n", title)
|
|
fmt.Printf(" ID: %s\n", identifier)
|
|
fmt.Printf(" Status: %s\n", status)
|
|
fmt.Printf(" Deadline: %s\n", deadline)
|
|
}
|
|
} else {
|
|
fmt.Println("No EIC Accelerator opportunities found")
|
|
}
|
|
}
|
|
|
|
// Helper function to safely get string values from map
|
|
func getStringValue(data map[string]interface{}, key string) string {
|
|
if value, ok := data[key].(string); ok {
|
|
return value
|
|
}
|
|
return "N/A"
|
|
}</content>
|
|
<parameter name="filePath">/Users/damirmukimov/city_resource_graph/eu_funding_api.go
|