Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open ai wrapper #1371

Open
wants to merge 29 commits into
base: development
Choose a base branch
from

Conversation

yash-sojitra
Copy link

#1242

Description:

  • wrote wrapper for chat completions endpoint of openai api
  • issue no 1242
  • used raw api endpoint instead of openai's own wrapper to eliminate an additional layer

Checklist:

  • [✅] I have formatted my code using goimport and golangci-lint.
  • [✅] All new code is covered by unit tests.
  • [✅] This PR does not decrease the overall code coverage.
  • [✅] I have reviewed the code comments and documentation for clarity.

@vikash
Copy link
Contributor

vikash commented Jan 8, 2025

Should we put this in datasource or in service package instead?

@yash-sojitra
Copy link
Author

Currently it's in data source. I had some confusions about this. So at last after that issue discussion I decided to build it in data source.

pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/logger.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/logger.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client_test.go Outdated Show resolved Hide resolved
@yash-sojitra
Copy link
Author

@ccoVeille I have updated the PR.

pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion_test.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion_test.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion_test.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
@yash-sojitra
Copy link
Author

@ccoVeille I have updated the pr and replied to some of the conversations.

Copy link
Contributor

@ccoVeille ccoVeille left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@yash-sojitra
Copy link
Author

@Umang01-hash approval with write access required for the PR. it's already reviewed.

@yash-sojitra
Copy link
Author

@Umang01-hash @vikash a review required with write access.

@yash-sojitra
Copy link
Author

@ccoVeille @Umang01-hash in workflow-pipeline PKG unit-testing v1.22 passes but PKG unit-testing v1.21 fails and says was cancelled.

Copy link
Member

@Umang01-hash Umang01-hash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! I have reviewed the changes, and I have a suggestion regarding the directory structure:

Since OpenAI is primarily a communication service and not a database, it would be more appropriate to place this under the service directory instead of datasource. This would better reflect its role as a service for generating responses.

Would you please consider moving the OpenAI integration to the service directory?

Also we need to make updates in the documentation regarding any new feature addition so that other users can know about it easily. Please also add the documenttaion regarding this wrapper and an example of how to use it.

pkg/gofr/datasource/openai/chatcompletion_test.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/chatcompletion.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client.go Outdated Show resolved Hide resolved
pkg/gofr/datasource/openai/client_test.go Outdated Show resolved Hide resolved
@yash-sojitra
Copy link
Author

is it okay ? i have placed openai folder in service folder.

@Umang01-hash
Copy link
Member

@yash-sojitra I think you might have forgot to push your commit..

@yash-sojitra
Copy link
Author

I was just asking i haven't yet committed changes.

@Umang01-hash
Copy link
Member

@yash-sojitra Please go ahead and commit the changes

@Umang01-hash
Copy link
Member

@yash-sojitra are you still active on the issue? Please let us know if you have any doubts regarding the PR or the issue

@yash-sojitra
Copy link
Author

Yupp I have done the changes to code. I didn't got much time to complete documentation. Will be doing in short time.

Also a thing I noticed since this is an optional service package I thought to add it to container struct just like external dbs are added and this open ai service will be added and accessible via gofr.context just like data sources. Is this approach to add OpenAI services good ?

@Umang01-hash
Copy link
Member

@yash-sojitra Please resolve these code quality issues as well as test failure in your PR:
Screenshot 2025-01-30 at 4 50 37 PM

@yash-sojitra
Copy link
Author

it's giving code quality error on files that i haven't modified for example it giving error in mockcontainer_test.go

image

@Umang01-hash
Copy link
Member

@yash-sojitra But for all the remaining PR's that we have all checks are passing. You also need to update mockContainer if you have updated container.

@yash-sojitra
Copy link
Author

in mockcontainer_test.go in Test_HttpServiceMock() three variables are unused. (highlighted with bold)

{85CCE29D-7AA6-4CBD-8578-7281F9ED6D9B}

@yash-sojitra
Copy link
Author

I fixed the above mentioned test but there is still one linting error that is occurring across several files.

File is not `gci`-ed with --skip-generated -s standard -s default -s localmodule (gci)go-golangci-lint

@Umang01-hash
Copy link
Member

Umang01-hash commented Jan 30, 2025

I fixed the above mentioned test but there is still one linting error that is occurring across several files.

File is not `gci`-ed with --skip-generated -s standard -s default -s localmodule (gci)go-golangci-lint

@yash-sojitra you can do it using this command : golangci-lint run --enable-only gci --fix

@yash-sojitra
Copy link
Author

func New() *App {

	app := &App{}

	app.readConfig(false)

	app.container = container.NewContainer(app.Config)

	app.initTracer()

	// Metrics Server

	port, err := strconv.Atoi(app.Config.Get("METRICS_PORT"))

	if err != nil || port <= 0 {

		port = defaultMetricPort

	}

	if !isPortAvailable(port) {

		app.container.Logger.Fatalf("metrics port %d is blocked or unreachable", port)

	}

	app.metricServer = newMetricServer(port)

	// HTTP Server

	port, err = strconv.Atoi(app.Config.Get("HTTP_PORT"))

	if err != nil || port <= 0 {

		port = defaultHTTPPort

	}

	app.httpServer = newHTTPServer(app.container, port, middleware.GetConfigs(app.Config))

	app.httpServer.certFile = app.Config.GetOrDefault("CERT_FILE", "")

	app.httpServer.keyFile = app.Config.GetOrDefault("KEY_FILE", "")

	// Add Default routes

	app.add(http.MethodGet, "/.well-known/health", healthHandler)

	app.add(http.MethodGet, "/.well-known/alive", liveHandler)

	app.add(http.MethodGet, "/favicon.ico", faviconHandler)

	app.checkAndAddOpenAPIDocumentation()

	if app.Config.Get("APP_ENV") == "DEBUG" {

		app.httpServer.RegisterProfilingRoutes()

	}

	// gRPC Server

	port, err = strconv.Atoi(app.Config.Get("GRPC_PORT"))

	if err != nil || port <= 0 {

		port = defaultGRPCPort

	}

	app.grpcServer = newGRPCServer(app.container, port)

	app.subscriptionManager = newSubscriptionManager(app.container)

	// static file server

	currentWd, _ := os.Getwd()

	checkDirectory := filepath.Join(currentWd, defaultPublicStaticDir)

	if _, err = os.Stat(checkDirectory); err == nil {

		app.AddStaticFiles(defaultPublicStaticDir, checkDirectory)

	}

	return app

}

it added a newline after every line. and it modified all the files like this.

@Umang01-hash
Copy link
Member

Screenshot 2025-01-31 at 12 34 32 PM @yash-sojitra All the tests are passing now. only a few linter comments and we will be ready to review the PR.

pkg/gofr/container/services.go Outdated Show resolved Hide resolved
pkg/gofr/services.go Outdated Show resolved Hide resolved
pkg/gofr/service/openai/openai.go Outdated Show resolved Hide resolved
@ccoVeille
Copy link
Contributor

Thanks for baring with my iterative feedbacks.

I know let @Umang01-hash or @coolwednesday take a look at the things I might have missed

@yash-sojitra
Copy link
Author

No problems. It was very insightful as it was my first issue into open source.

@ccoVeille
Copy link
Contributor

No problems. It was very insightful as it was my first issue into open source.

You did right then. I can tell by the way you reacted to the feedbacks that you were open to critics. You confirm it by telling you find feedbacks insightful.

We all started with open-source PR. Yours is pretty good.

@yash-sojitra
Copy link
Author

yash-sojitra commented Feb 1, 2025

@Umang01-hash @coolwednesday PR is ready for review.

Comment on lines 17 to 25
func Test_HttpServiceMock(t *testing.T) {
test := struct {
desc string
path string
statusCode int
expectedRes string
}{

desc: "simple service handler",
path: "/fact",
expectedRes: `{"data":{"fact":"Cats have 3 eyelids.","length":20}}` + "\n",
statusCode: 200,
}

httpservices := []string{"cat-facts", "cat-facts1", "cat-facts2"}

_, mock := NewMockContainer(t, WithMockHTTPService(httpservices...))

res := httptest.NewRecorder()
res.Body = bytes.NewBufferString(`{"fact":"Cats have 3 eyelids.","length":20}` + "\n")
res.Code = test.statusCode
res.Code = 200
result := res.Result()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I know why this test has been removed ?

Copy link
Author

@yash-sojitra yash-sojitra Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only statusCode field was used in test struct. So the linter was giving error about other three unused fields. Since only one field was used from the test struct I removed it and manually updated the status code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{2F078F26-22B9-426C-B391-12C0198AE163}

This gives linter error and breaks in code check.

Comment on lines +9 to +11
// implementation of chat endpoint of openai api
CreateCompletions(ctx context.Context, r any) (any, error)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give a better name, createCompletion sounds confusing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is OpenAI's nomenclature.

pkg/gofr/service/openai/openai.go Outdated Show resolved Hide resolved
Comment on lines 154 to 170
// Get makes a get request.
func (c *Client) Get(ctx context.Context, url string) (response []byte, err error) {
resp, err := c.Call(ctx, http.MethodGet, url, nil)
if err != nil {
c.logger.Errorf("%v", err)
return response, err
}
defer resp.Body.Close()

response, err = io.ReadAll(resp.Body)
if err != nil {
c.logger.Errorf("%v", err)
}

return response, err
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I know where are we actually calling this function ? Even if I remove it I do not see any dependency. Did iI miss anything ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this chat completion is only one end point I have kept it for future use where we need to add more OpenAI endpoints.

pkg/gofr/service/openai/logger.go Outdated Show resolved Hide resolved
docs/advanced-guide/using-openai-api/page.md Outdated Show resolved Hide resolved
@Umang01-hash
Copy link
Member

@yash-sojitra Please complete the review changes suggested by @coolwednesday. And please also resolve the merge conflicts in your PR.

@yash-sojitra
Copy link
Author

@coolwednesday i have some comments on conversation if you can review about it. other changes i have done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants