Vijayabhasker Uppara commited on
Commit
d2eb724
·
1 Parent(s): 4d92393

initial Commit

Browse files
Files changed (3) hide show
  1. Dockerfile +24 -0
  2. app.py +169 -0
  3. requirements.txt +5 -0
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies
6
+ RUN apt-get update && apt-get install -y \
7
+ build-essential \
8
+ curl \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Copy requirements first for better caching
12
+ COPY requirements.txt .
13
+
14
+ # Install Python dependencies
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Copy application code
18
+ COPY . .
19
+
20
+ # Expose port
21
+ EXPOSE 7860
22
+
23
+ # Command to run the application
24
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Address Detection and Summarization API for Hugging Face Spaces
4
+ """
5
+
6
+ from fastapi import FastAPI, HTTPException, Header
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from pydantic import BaseModel, Field
9
+ import os
10
+ from enum import Enum
11
+ from typing import Dict, Optional, Annotated
12
+ import logging
13
+ from dotenv import load_dotenv
14
+
15
+ # Load environment variables
16
+ load_dotenv()
17
+
18
+ # Configure logging
19
+ logging.basicConfig(level=logging.INFO)
20
+ logger = logging.getLogger(__name__)
21
+
22
+ app = FastAPI(title="Address Detection and Summarization API")
23
+
24
+ # Add CORS middleware for Hugging Face Spaces
25
+ app.add_middleware(
26
+ CORSMiddleware,
27
+ allow_origins=["*"],
28
+ allow_credentials=True,
29
+ allow_methods=["*"],
30
+ allow_headers=["*"],
31
+ )
32
+
33
+ class Actions(Enum):
34
+ DETECT_ADDRESS = "detect_address"
35
+ SUMMARIZE = "summarize"
36
+
37
+ # Request model
38
+ class RequestModel(BaseModel):
39
+ entity_urn: str = Field(..., description="Unique identifier for the entity")
40
+ content: str = Field(..., description="Content to be processed")
41
+
42
+ # Response models
43
+ class ResponseModel(BaseModel):
44
+ message: str = Field(description="Result of the operation, e.g., 'success' or 'failure'")
45
+ result: str = Field(description="summary in case of summarization, or || separated addresses in case of address detection")
46
+ action_type: Actions = Field(..., description="Type of action performed")
47
+ entity_urn: str = Field(..., description="Unique identifier for the entity")
48
+ sentiment: Optional[Dict] = Field(default=None, description="Sentiment analysis result")
49
+
50
+
51
+ @app.get("/")
52
+ async def root():
53
+ return {
54
+ "message": "Address Detection and Summarization API",
55
+ "version": "1.0.0",
56
+ "status": "healthy",
57
+ "endpoints": {
58
+ "address_detection": "/address-detection",
59
+ "summarization": "/summarize",
60
+ "health": "/health",
61
+ "docs": "/docs"
62
+ }
63
+ }
64
+
65
+ @app.get("/health")
66
+ async def health_check():
67
+ return {
68
+ "status": "healthy",
69
+ "service": "Address Detection and Summarization API",
70
+ "version": "1.0.0"
71
+ }
72
+
73
+ def extract_address(text: str) -> str:
74
+ address_pattern = r'\d+\s+[A-Za-z\s]+(?:Street|St|Avenue|Ave|Road|Rd|Boulevard|Blvd|Lane|Ln|Drive|Dr|Court|Ct|Place|Pl)'
75
+ match = re.search(address_pattern, text, re.IGNORECASE)
76
+ return match.group().strip() if match else ""
77
+
78
+ def extract_summary(text: str) -> str:
79
+ sentences = text.split(".")
80
+ return ". ".join(sentences[:3]).strip() + "." if sentences else ""
81
+
82
+
83
+ @app.post("/address-detection", response_model=ResponseModel)
84
+ async def address_detection(
85
+ request: RequestModel,
86
+ openai_api_key: Annotated[str, Header(alias="x-api-key")]
87
+ ):
88
+ """Endpoint for address detection"""
89
+ try:
90
+ logger.info(f"Processing address detection for entity_urn: {request.entity_urn}")
91
+
92
+ if not request.content.strip():
93
+ return ResponseModel(
94
+ message="failure",
95
+ result="Content is empty",
96
+ action_type=Actions.DETECT_ADDRESS,
97
+ entity_urn=request.entity_urn,
98
+ sentiment=None
99
+ )
100
+
101
+ addresses = extract_address(request.content)
102
+
103
+ return ResponseModel(
104
+ message="success",
105
+ result=addresses,
106
+ action_type=Actions.DETECT_ADDRESS,
107
+ entity_urn=request.entity_urn,
108
+ sentiment=None
109
+ )
110
+
111
+ except Exception as e:
112
+ logger.error(f"Address detection endpoint error: {str(e)}")
113
+ return ResponseModel(
114
+ message="failure",
115
+ result=f"Error: {str(e)}",
116
+ action_type=Actions.DETECT_ADDRESS,
117
+ entity_urn=request.entity_urn,
118
+ sentiment=None
119
+ )
120
+
121
+ @app.post("/summarize", response_model=ResponseModel)
122
+ async def summarize(
123
+ request: RequestModel,
124
+ openai_api_key: Annotated[str, Header(alias="x-api-key")]
125
+ ):
126
+ """Endpoint for text summarization and sentiment analysis"""
127
+ try:
128
+ logger.info(f"Processing summarization for entity_urn: {request.entity_urn}")
129
+
130
+ if not request.content.strip():
131
+ return ResponseModel(
132
+ message="failure",
133
+ result="Content is empty",
134
+ action_type=Actions.SUMMARIZE,
135
+ entity_urn=request.entity_urn,
136
+ sentiment={}
137
+ )
138
+
139
+ summary = extract_summary(request.content)
140
+
141
+ sentiment = {
142
+ "label": "POSITIVE",
143
+ "score": 0.95
144
+ }
145
+
146
+
147
+ return ResponseModel(
148
+ message="success",
149
+ result=summary,
150
+ sentiment=sentiment,
151
+ action_type=Actions.SUMMARIZE,
152
+ entity_urn=request.entity_urn
153
+ )
154
+
155
+ except Exception as e:
156
+ logger.error(f"Summarization endpoint error: {str(e)}")
157
+ return ResponseModel(
158
+ message="failure",
159
+ result=f"Error: {str(e)}",
160
+ sentiment={},
161
+ action_type=Actions.SUMMARIZE,
162
+ entity_urn=request.entity_urn
163
+ )
164
+
165
+ if __name__ == "__main__":
166
+ import uvicorn
167
+ # Use port 7860 for Hugging Face Spaces, fallback to 8500 for local
168
+ port = int(os.getenv("PORT", 7860))
169
+ uvicorn.run(app, host="0.0.0.0", port=port)
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi==0.115.14
2
+ uvicorn[standard]==0.34.3
3
+ pydantic==2.11.7
4
+ python-dotenv==1.1.1
5
+ httpx==0.28.1