Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
pse-trapp-public
IntentFinder
Commits
eb67e728
Commit
eb67e728
authored
Jun 15, 2021
by
Patrick Schlindwein
Browse files
Merge branch 'feat/#64_add_openapi_defintion' into 'master'
#64
Implemented OpenAPI See merge request
!72
parents
98cfe1f8
3a242137
Pipeline
#75417
passed with stages
in 2 minutes and 37 seconds
Changes
22
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.gitmodules
0 → 100644
View file @
eb67e728
[submodule "src/ktor-server/openapigen"]
path = src/ktor-server/openapigen
url = https://github.com/papsign/Ktor-OpenAPI-Generator.git
src/ktor-server/build.gradle
View file @
eb67e728
...
...
@@ -14,8 +14,11 @@ repositories {
maven
{
url
"https://kotlin.bintray.com/kotlinx"
}
maven
{
url
'https://jitpack.io'
}
}
apply
plugin:
'kotlin'
dependencies
{
implementation
"io.ktor:ktor-gson:$ktor_version"
implementation
"io.ktor:ktor-server-core:$ktor_version"
...
...
@@ -39,6 +42,8 @@ dependencies {
// for logging
implementation
"ch.qos.logback:logback-classic:$logback_version"
implementation
'com.github.papsign:Ktor-OpenAPI-Generator:-SNAPSHOT'
// for docx
// https://mvnrepository.com/artifact/org.apache.poi/poi
implementation
group:
'org.apache.poi'
,
name:
'poi'
,
version:
'5.0.0'
...
...
openapigen
@
546734c4
Subproject commit 546734c4467036958637a32f4f84c4c4ef044789
src/ktor-server/settings.gradle
View file @
eb67e728
rootProject
.
name
=
'ktor-server'
include
'openapigen'
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/Application.kt
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server
import
de.h_da.fbi.smebt.intentfinder.server.nlp.PythonBridge
import
com.google.gson.GsonBuilder
import
com.papsign.ktor.openapigen.OpenAPIGen
import
com.papsign.ktor.openapigen.openAPIGen
import
com.papsign.ktor.openapigen.route.apiRouting
import
com.papsign.ktor.openapigen.route.tag
import
com.papsign.ktor.openapigen.schema.namer.DefaultSchemaNamer
import
com.papsign.ktor.openapigen.schema.namer.SchemaNamer
import
de.h_da.fbi.smebt.intentfinder.server.routing.docx.docxRoutes
import
de.h_da.fbi.smebt.intentfinder.server.routing.summarization.summarizationRoutes
import
de.h_da.fbi.smebt.intentfinder.server.routing.tags.Tags
import
de.h_da.fbi.smebt.intentfinder.server.routing.upload.uploadRoutes
import
de.h_da.fbi.smebt.intentfinder.server.upload.registerApiRoutes
import
io.ktor.application.*
import
io.ktor.features.*
import
io.ktor.http.*
import
io.ktor.request.*
import
io.ktor.response.*
import
io.ktor.routing.*
import
io.ktor.serialization.*
import
kotlinx.serialization.json.Json
import
java.lang.RuntimeException
import
de.h_da.fbi.smebt.intentfinder.server.upload.registerApiRoutes
import
kotlin.reflect.KType
fun
main
(
args
:
Array
<
String
>):
Unit
=
io
.
ktor
.
server
.
netty
.
EngineMain
.
main
(
args
)
fun
Application
.
module
()
{
install
(
OpenAPIGen
)
{
info
{
version
=
"0.0.1"
title
=
"IntentFinder API"
description
=
"The IntentFinder API to extract question-answer pairs from URLs or several file types."
contact
{
name
=
"Hochschule Darmstadt PSE SS21"
url
=
"https://code.fbi.h-da.de/pse-trapp-public/intentfinder"
}
}
server
(
"http://localhost:8080/"
)
{
description
=
"Local server"
}
replaceModule
(
DefaultSchemaNamer
,
object
:
SchemaNamer
{
val
regex
=
Regex
(
"[A-Za-z0-9_.]+"
)
override
fun
get
(
type
:
KType
):
String
{
return
type
.
toString
().
replace
(
regex
)
{
it
.
value
.
split
(
"."
).
last
()
}.
replace
(
Regex
(
">|<|, "
),
"_"
)
}
})
}
install
(
ContentNegotiation
)
{
json
()
}
...
...
@@ -30,44 +62,29 @@ fun Application.module() {
}
routing
{
post
(
"/summarize"
)
{
val
req
=
call
.
receive
<
SummaryRequest
>()
val
response
=
PythonBridge
().
getSummary
(
req
.
text
,
req
.
maxLength
)
call
.
respond
(
response
)
get
(
"/"
)
{
call
.
respondRedirect
(
"/swagger-ui/index.html?url=/openapi.json"
,
true
)
}
post
(
"/{name}"
)
{
}
// get faq with Json Configuration
get
(
"/faqResource"
)
{
// Rückgabe Json Object (vgl. #38)
}
// Definition eines Endpunkts zur Definition einer Docx-Datei mit JSON-Konfiguration
post
(
"{chatbotId}/docxResource/{filename}"
)
{
get
(
"/openapi.json"
)
{
call
.
respond
(
GsonBuilder
().
create
().
toJson
(
application
.
openAPIGen
.
api
.
serialize
()))
}
}
// get docx file with Json Configuration
get
(
"/docxResource"
)
{
//Rückgabe Json Object (vgl. #37
)
apiRouting
{
tag
(
Tags
.
SUMMARIZE
)
{
summarizationRoutes
(
)
}
// Definition endpoint zum Auslesen aller hochgeladener docx mit status
get
(
"/files"
)
{
tag
(
Tags
.
INTENT_FINDER
)
{
uploadRoutes
()
docxRoutes
()
}
// Routen ohne Funktionalität
routing
{
tag
(
Tags
.
DEPRECATED
)
{
registerApiRoutes
()
}
}
// registerUploadRoutes()
registerApiRoutes
()
}
class
InternalServerErrorException
:
RuntimeException
()
...
...
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/nlp/client/RetrofitClient.kt
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.nlp.client
import
com.google.gson.JsonObject
import
de.h_da.fbi.smebt.intentfinder.server.SummaryRequest
import
de.h_da.fbi.smebt.intentfinder.server.
nlp.dto.
SummaryRequest
import
de.h_da.fbi.smebt.intentfinder.server.nlp.dto.Strategies
import
de.h_da.fbi.smebt.intentfinder.server.nlp.dto.Summary
import
okhttp3.OkHttpClient
...
...
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/nlp/client/SummarizationAPI.kt
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.nlp.client
import
com.google.gson.JsonObject
import
de.h_da.fbi.smebt.intentfinder.server.SummaryRequest
import
de.h_da.fbi.smebt.intentfinder.server.
nlp.dto.
SummaryRequest
import
de.h_da.fbi.smebt.intentfinder.server.nlp.dto.Strategies
import
de.h_da.fbi.smebt.intentfinder.server.nlp.dto.Summary
import
retrofit2.Call
...
...
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/nlp/dto/Summary.kt
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.nlp.dto
import
com.papsign.ktor.openapigen.annotations.Response
import
kotlinx.serialization.Serializable
@Serializable
@Response
(
"Summary including used strategy and quality."
,
statusCode
=
200
)
data class
SummaryBody
(
val
strategy
:
String
,
val
quality
:
Double
,
val
summary
:
String
,
)
)
{
companion
object
{
val
EXAMPLE
=
SummaryBody
(
"UsedStrategy"
,
0.9
,
"My short and good strategy"
)
}
}
@Serializable
data class
Summary
(
...
...
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/SummaryRequest.kt
→
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/
nlp/dto/
SummaryRequest.kt
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server;
package
de.h_da.fbi.smebt.intentfinder.server
.nlp.dto
;
import
kotlinx.serialization.Serializable
...
...
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/docx/DocxRoutes.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.docx
import
com.papsign.ktor.openapigen.route.info
import
com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute
import
com.papsign.ktor.openapigen.route.path.normal.get
import
com.papsign.ktor.openapigen.route.path.normal.post
import
com.papsign.ktor.openapigen.route.response.respond
import
com.papsign.ktor.openapigen.route.route
import
de.h_da.fbi.smebt.intentfinder.server.routing.docx.dto.DocxJsonConfigurationRequest
import
kotlinx.serialization.json.*
fun
NormalOpenAPIRoute
.
docxRoutes
()
{
route
(
"faqResource"
)
{
get
<
Any
,
Any
>(
info
(
summary
=
"Get FAQ with json configuration"
,
description
=
"Not yet implemented, dummy endpoint."
)
)
{
// TODO implement
respond
(
buildJsonObject
{
put
(
"key"
,
"some value"
)
})
}
}
route
(
"{name}"
)
{
post
<
String
,
Any
,
Any
>
(
info
(
summary
=
"Define docx file"
,
description
=
"Define docx file with JSON configuration."
),
exampleRequest
=
DocxJsonConfigurationRequest
.
EXAMPLE
)
{
name
,
_
->
// TODO implement
respond
(
name
)
}
}
route
(
"docxResource"
)
{
get
<
Any
,
Any
>(
info
(
summary
=
"Define docx file"
,
description
=
"Define docx file with JSON configuration."
),
)
{
// TODO implement
respond
(
buildJsonObject
{
put
(
"key"
,
"some value"
)
})
}
}
route
(
"files"
)
{
get
<
Any
,
List
<
Any
>>(
info
(
summary
=
"Read all uploaded docx file"
,
description
=
"Returns all uploaded docx files with status."
),
)
{
// TODO implement
respond
(
listOf
(
"This could be a list of files."
))
}
}
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/docx/dto/DocxJsonConfigurationRequest.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.docx.dto
import
com.papsign.ktor.openapigen.annotations.Request
import
com.papsign.ktor.openapigen.annotations.parameters.PathParam
import
kotlinx.serialization.Required
import
kotlinx.serialization.Serializable
@Request
(
"DocxJsonConfiguration request params"
)
@Serializable
data class
DocxJsonConfigurationRequest
(
@Required
@PathParam
(
"Chatbot Id"
)
val
chatbotId
:
String
,
@Required
@PathParam
(
"Filename"
)
val
filename
:
String
)
{
companion
object
{
val
EXAMPLE
=
DocxJsonConfigurationRequest
(
"CB_123"
,
"MyFilename.docx"
)
}
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/summarization/SummaryRoutes.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.summarization
import
com.papsign.ktor.openapigen.route.info
import
com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute
import
com.papsign.ktor.openapigen.route.path.normal.post
import
com.papsign.ktor.openapigen.route.response.respond
import
com.papsign.ktor.openapigen.route.route
import
de.h_da.fbi.smebt.intentfinder.server.nlp.PythonBridge
import
de.h_da.fbi.smebt.intentfinder.server.nlp.dto.SummaryBody
import
de.h_da.fbi.smebt.intentfinder.server.routing.summarization.dto.SummaryPostRequestBody
fun
NormalOpenAPIRoute
.
summarizationRoutes
()
{
route
(
"summarize"
)
{
post
<
Any
,
List
<
SummaryBody
>,
SummaryPostRequestBody
>(
info
(
summary
=
"Summarize a given text"
,
description
=
"Summarizes a given text in consideration of maximum amount of sentences."
),
exampleRequest
=
SummaryPostRequestBody
.
EXAMPLE
,
exampleResponse
=
listOf
(
SummaryBody
.
EXAMPLE
)
)
{
_
,
body
->
val
response
=
PythonBridge
().
getSummary
(
body
.
text
,
body
.
maxLength
)
respond
(
response
)
}
}
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/summarization/dto/SummaryPostRequestBody.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.summarization.dto
import
com.papsign.ktor.openapigen.annotations.Request
import
kotlinx.serialization.Required
import
kotlinx.serialization.Serializable
@Request
(
"Summarize request body."
)
@Serializable
data class
SummaryPostRequestBody
(
@Required
val
text
:
String
,
@Required
val
maxLength
:
Int
)
{
companion
object
{
val
EXAMPLE
=
SummaryPostRequestBody
(
"This is my text I want summarized. As maxLength I will pass the maximum amount of sentences the summarization should contain."
,
3
)
}
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/tags/Tags.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.tags
import
com.papsign.ktor.openapigen.APITag
enum
class
Tags
(
override
val
description
:
String
)
:
APITag
{
INTENT_FINDER
(
"IntentFinder"
),
SUMMARIZE
(
"Summarize"
),
DEPRECATED
(
"Deprecated"
)
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/UploadRoutes.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload
import
com.papsign.ktor.openapigen.route.info
import
com.papsign.ktor.openapigen.route.path.normal.NormalOpenAPIRoute
import
com.papsign.ktor.openapigen.route.path.normal.post
import
com.papsign.ktor.openapigen.route.path.normal.put
import
com.papsign.ktor.openapigen.route.route
import
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto.*
fun
NormalOpenAPIRoute
.
uploadRoutes
()
{
// TODO as soon as those methods are ported remove the `new/` prefix in the routing
route
(
"new/"
)
{
route
(
"upload"
)
{
post
<
Any
,
Any
,
UploadFileRequestBody
>(
info
(
summary
=
"Upload file"
,
description
=
"Uploads a file"
)
)
{
_
,
body
->
// TODO What to actually do here? Code does nothing
// TODO Use file stream instead of multipart stuff
}
}
route
(
"{chatbotId}/file"
)
{
post
<
UploadDocxRequestParams
,
FileStatusResponse
,
UploadDocxRequestBody
>(
info
(
summary
=
"Upload a .docx file"
,
description
=
"Upload a .docx file and save it."
),
exampleResponse
=
FileStatusResponse
.
EXAMPLE
)
{
params
,
body
->
// TODO port to proper file handling
}
}
route
(
"{chatbotId}/file/{id}/{filename}"
)
{
put
<
ModifyDocxRequestParams
,
FileStatusResponse
,
UploadDocxRequestBody
>(
info
(
summary
=
"Modify a .docx file"
,
description
=
"Modify an existing .docx file and save it."
),
exampleResponse
=
FileStatusResponse
.
EXAMPLE
)
{
params
,
body
->
// TODO port to proper file handling
}
}
route
(
"{chatbotId}/faqResource/{jsonStructure}"
)
{
post
<
UploadJsonConfigRequestParams
,
UploadJsonConfigResponse
,
UploadFileRequestBody
>(
info
(
summary
=
"Define a FAQ website"
,
description
=
"Define a FAQ website with JSON configuration."
),
exampleResponse
=
UploadJsonConfigResponse
.
EXAMPLE
)
{
params
,
body
->
// TODO port to proper file handling
}
}
}
}
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/dto/FileStatusResponse.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto
import
com.papsign.ktor.openapigen.annotations.Response
import
kotlinx.serialization.Serializable
@Serializable
@Response
(
"File status response."
,
statusCode
=
200
)
data class
FileStatusResponse
(
val
path
:
String
,
val
status
:
String
)
{
companion
object
{
val
EXAMPLE
=
FileStatusResponse
(
"uploads/myFile.docx"
,
"created"
)
}
}
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/dto/ModifyDocxRequest.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto
import
com.papsign.ktor.openapigen.annotations.Request
import
com.papsign.ktor.openapigen.annotations.parameters.PathParam
import
com.papsign.ktor.openapigen.content.type.multipart.FormDataRequest
import
com.papsign.ktor.openapigen.content.type.multipart.NamedFileInputStream
import
com.papsign.ktor.openapigen.content.type.multipart.PartEncoding
import
kotlinx.serialization.Required
import
kotlinx.serialization.Serializable
@FormDataRequest
data class
ModifyDocxRequestBody
(
@PartEncoding
(
"multipart/form-data"
)
@Required
val
file
:
NamedFileInputStream
)
@Request
(
"Modify existing .docx request parameters."
)
@Serializable
data class
ModifyDocxRequestParams
(
@Required
@PathParam
(
"Specify Chatbot ID"
)
val
chatbotId
:
String
,
@Required
@PathParam
(
"ID"
)
val
id
:
String
,
@Required
@PathParam
(
"Specify file name"
)
val
filename
:
String
)
\ No newline at end of file
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/dto/UploadDocxRequest.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto
import
com.papsign.ktor.openapigen.annotations.Request
import
com.papsign.ktor.openapigen.annotations.parameters.PathParam
import
com.papsign.ktor.openapigen.content.type.multipart.FormDataRequest
import
com.papsign.ktor.openapigen.content.type.multipart.NamedFileInputStream
import
com.papsign.ktor.openapigen.content.type.multipart.PartEncoding
import
kotlinx.serialization.Required
import
kotlinx.serialization.Serializable
@FormDataRequest
data class
UploadDocxRequestBody
(
@PartEncoding
(
"multipart/form-data"
)
@Required
val
file
:
NamedFileInputStream
)
@Request
(
"Upload .docx request parameters."
)
@Serializable
data class
UploadDocxRequestParams
(
@Required
@PathParam
(
"Specify Chatbot ID"
)
val
chatbotId
:
String
)
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/dto/UploadJsonConfig.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto
import
com.papsign.ktor.openapigen.annotations.Request
import
com.papsign.ktor.openapigen.annotations.Response
import
com.papsign.ktor.openapigen.annotations.parameters.PathParam
import
kotlinx.serialization.Required
import
kotlinx.serialization.Serializable
@Request
(
"Upload a JSON config."
)
@Serializable
data class
UploadJsonConfigRequestParams
(
@Required
@PathParam
(
"Title of the JSON config"
)
val
jsonStructure
:
String
)
@Serializable
@Response
(
"File status response."
,
statusCode
=
200
)
data class
UploadJsonConfigResponse
(
val
numberOfPairs
:
Int
)
{
companion
object
{
val
EXAMPLE
=
UploadJsonConfigResponse
(
12
)
}
}
src/ktor-server/src/main/kotlin/de/h_da/fbi/smebt/intentfinder/server/routing/upload/dto/UploadPostRequest.kt
0 → 100644
View file @
eb67e728
package
de.h_da.fbi.smebt.intentfinder.server.routing.upload.dto
import
com.papsign.ktor.openapigen.content.type.multipart.FormDataRequest
import
com.papsign.ktor.openapigen.content.type.multipart.NamedFileInputStream
import
com.papsign.ktor.openapigen.content.type.multipart.PartEncoding
import
kotlinx.serialization.Required
@FormDataRequest
data class
UploadFileRequestBody
(
@PartEncoding
(
"multipart/form-data"
)
@Required
val
file
:
NamedFileInputStream
)
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment