### Go gRPC Client Usage for CompanyFinder.ByINN Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Demonstrates how to connect to a running gRPC server and call the ByINN method using the generated Go client. Includes examples for successful lookups and handling not-found cases. ```go package main import ( "context" "fmt" "log" "google.golang.org/grpc" "github.com/DmitriiKumancev/rusprofile-grpc/pkg" ) func main() { // Connect to the running gRPC server conn, err := grpc.Dial("localhost:8888", grpc.WithInsecure()) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() client := pkg.NewCompanyFinderClient(conn) // Successful lookup company, err := client.ByINN(context.Background(), &pkg.INN{INN: "5902879646"}) if err != nil { log.Fatalf("ByINN failed: %v", err) // gRPC status error with code NOT_FOUND } fmt.Printf("Name: %s\nINN: %s\nKPP: %s\nCEO: %s\n", company.Name, company.INN, company.KPP, company.CEO) // Output: // Name: ООО "Иксолла" // INN: 5902879646 // KPP: 590201001 // CEO: Чемоданова Валентина Игоревна // Not-found case _, err = client.ByINN(context.Background(), &pkg.INN{INN: "123"}) if err != nil { fmt.Println(err) // rpc error: code = NotFound desc = no company with provided INN } } ``` -------------------------------- ### Test HTTP API with curl Source: https://github.com/dmitriikumancev/rusprofile-wrapper/blob/main/README.md Use curl to test the HTTP API endpoint for company information by INN. Shows examples for both a non-existent INN and a valid one, demonstrating 'not found' and '200' responses. ```shell # Returns 'not found' curl localhost:8080/v1/company/123 # Returns '200' curl localhost:8080/v1/company/5003028028 ``` -------------------------------- ### GET /v1/company/{INN} - HTTP/JSON Gateway Endpoint Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt This HTTP endpoint mirrors the gRPC `ByINN` method, providing access to company information via a RESTful interface. It returns a JSON-encoded `Company` object on success or a JSON error body with an HTTP 404 status if the INN is not found. ```APIDOC ## GET /v1/company/{INN} ### Description Mirrors the gRPC API over REST. Returns a JSON-encoded `Company` object on success, or a JSON error body with an HTTP 404 status when the INN is not found. The gateway is automatically bridged to the gRPC server via `grpc-gateway`. ### Method GET ### Endpoint `/v1/company/{INN}` ### Parameters #### Path Parameters - **INN** (string) - Required - The taxpayer identification number of the company. ### Request Example ```shell curl http://localhost:8080/v1/company/5902879646 ``` ### Response #### Success Response (200) - **INN** (string) - The taxpayer identification number. - **KPP** (string) - The reason code for registration. - **name** (string) - The full company name. - **CEO** (string) - The name of the CEO. #### Response Example ```json { "INN": "5902879646", "KPP": "590201001", "name": "ООО \"Иксолла\"", "CEO": "Чемоданова Валентина Игоревна" } ``` #### Error Response (404) - **code** (integer) - The error code (e.g., 5 for Not Found). - **message** (string) - A description of the error (e.g., "no company with provided INN"). - **details** (array) - An array for additional error details (usually empty). #### Response Example ```json { "code": 5, "message": "no company with provided INN", "details": [] } ``` ``` -------------------------------- ### Build and Run Rusprofile gRPC Service from Source Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Instructions for cloning the repository, building, and running the service locally using Go or Make. Optional flags can customize ports and file paths. ```shell # Clone and build git clone https://github.com/DmitriiKumancev/rusprofile-grpc.git cd rusprofile-grpc # Run directly with Go go run ./cmd/rusprofile-grpc # Or with make make run # Optional flags (defaults shown): go run ./cmd/rusprofile-grpc \ -grpc-port=8888 \ -http-port=8080 \ -swagger-spec=./api/openapiv2/rusprofile-grpc.swagger.json \ -static-files=./static/web ``` -------------------------------- ### Generate Go Protobuf, gRPC, and Gateway Files Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Instructions for regenerating all Go protobuf, gRPC, and gateway files from the .proto source using buf. This process generates essential files for gRPC communication and HTTP API exposure. ```shell # Install buf (if not already installed) go install github.com/bufbuild/buf/cmd/buf@latest # Generate all artifacts (runs buf generate inside ./api) make proto-generate # Equivalent to: cd ./api && buf generate # Generated output files: # pkg/rusprofile-grpc.pb.go — protobuf message types # pkg/rusprofile-grpc_grpc.pb.go — gRPC server/client interfaces # pkg/rusprofilegrpc.pb.gw.go — grpc-gateway HTTP handler # api/openapiv2/rusprofile-grpc.swagger.json — Swagger spec # buf configuration (api/buf.gen.yaml) controls output plugins: # - protoc-gen-go → message structs # - protoc-gen-go-grpc → service interfaces # - protoc-gen-grpc-gateway → HTTP mux registration # - protoc-gen-openapiv2 → Swagger JSON ``` -------------------------------- ### CompanyFinder.ByINN Go gRPC Client Usage Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Demonstrates how to connect to the gRPC server and use the `ByINN` method of the `CompanyFinderClient` to retrieve company details. ```APIDOC ## CompanyFinder.ByINN ### Description This method allows you to find company information by providing its INN (Taxpayer Identification Number). ### Method gRPC ### Endpoint N/A (gRPC service) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **INN** (string) - Required - The INN of the company to search for. ### Request Example ```go client.ByINN(context.Background(), &pkg.INN{INN: "5902879646"}) ``` ### Response #### Success Response (200) - **Name** (string) - The name of the company. - **INN** (string) - The INN of the company. - **KPP** (string) - The KPP (Reason Code for Registration) of the company. - **CEO** (string) - The name of the company's CEO. #### Response Example ```json { "Name": "ООО \"Иксолла\"", "INN": "5902879646", "KPP": "590201001", "CEO": "Чемоданова Валентина Игоревна" } ``` #### Error Response - **gRPC status NOT_FOUND**: Returned if no company with the provided INN is found. - **gRPC status Internal**: Returned if the HTTP request or JSON parsing fails. ``` -------------------------------- ### Build and Publish Docker Image Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Commands for building, tagging, and pushing the Docker image for the rusprofile-grpc service. Includes options for running the image with port mapping. ```shell # Build the Docker image (tag defaults to v1.0.1) make build-image # Equivalent to: docker build -t dmkumantsev/rusprofile-grpc:v1.0.1 -f ./build/rusprofile-grpc.dockerfile . # Push to Docker Hub make push-image # Build and push in one step make build-push-image # Run the image with port mapping make run-image # Equivalent to: docker run -it -p 8080:8080 -p 8888:8888 --rm dmkumantsev/rusprofile-grpc:v1.0.1 ``` -------------------------------- ### gRPC Lookup by INN using grpcurl Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Demonstrates successful and failed lookups using `grpcurl` against the gRPC server. Ensure the service is running on localhost:8888. ```shell # Successful lookup — returns company data grpcurl -plaintext -d '{"INN": "5902879646"}' localhost:8888 rusprofile.v1.CompanyFinder/ByINN # Expected output: # { # "INN": "5902879646", # "KPP": "590201001", # "name": "ООО \"Иксолла\"", # "CEO": "Чемоданова Валентина Игоревна" # } # Failed lookup — INN not found grpcurl -plaintext -d '{"INN": "123"}' localhost:8888 rusprofile.v1.CompanyFinder/ByINN # Expected output: # ERROR: # Code: NotFound # Message: no company with provided INN # List available services (reflection is enabled) grpcurl -plaintext localhost:8888 list # rusprofile.v1.CompanyFinder # Describe the service grpcurl -plaintext localhost:8888 describe rusprofile.v1.CompanyFinder ``` -------------------------------- ### Running Tests for Rusprofile gRPC Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Instructions on how to execute all unit and integration tests for the rusprofile-grpc project. Note that tests require internet access as they make real network requests to rusprofile.ru. ```shell # Run all unit and integration tests make test # Equivalent to: go test ./... # The test suite covers: # - pkg/finder_test.go : unit tests for CompanyFinder.ByINN (calls rusprofile.ru directly) # - cmd/.../main_test.go : integration tests starting live gRPC + HTTP servers # # Example test case (Xsolla / INN 5902879646): # want: &Company{INN: "5902879646", KPP: "590201001", # Name: `ООО "Иксолла"`, CEO: "Чемоданова Валентина Игоревна"} # # Note: tests make real network requests to rusprofile.ru — internet access required. ``` -------------------------------- ### Run Rusprofile gRPC Service with Docker Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Use this command to pull and run the pre-built Docker image. Ports 8080 (HTTP/Swagger) and 8888 (gRPC) are exposed. ```shell # Pull and run the service docker run -it -p 8080:8080 -p 8888:8888 --rm dmkumantsev/rusprofile-grpc:v1.0.1 # The following endpoints become available: # gRPC server: localhost:8888 # HTTP gateway: http://localhost:8080/v1/company/{INN} # Swagger UI: http://localhost:8080/swagger-ui/ # Swagger spec: http://localhost:8080/swagger.json ``` -------------------------------- ### Initialize Swagger UI Source: https://github.com/dmitriikumancev/rusprofile-wrapper/blob/main/static/web/index.html Initializes the Swagger UI with the API specification URL and configuration options. This is typically used to embed an interactive API documentation interface. ```javascript window.onload = function() { const ui = SwaggerUIBundle({ url: `${document.location.origin}/swagger.json`, dom_id: '#swagger-ui', deepLinking: true, presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset], plugins: [SwaggerUIBundle.plugins.DownloadUrl], layout: "StandaloneLayout" }); window.ui = ui; }; ``` -------------------------------- ### Run Docker Container Source: https://github.com/dmitriikumancev/rusprofile-wrapper/blob/main/README.md Execute this command to launch the Rusprofile gRPC wrapper service in a Docker container. It maps ports 8080 and 8888 for HTTP and gRPC access respectively. ```shell docker run -it -p 8080:8080 -p 8888:8888 --rm dmkumantsev/rusprofile-grpc:v1.0.1 ``` -------------------------------- ### Test gRPC API with grpcurl Source: https://github.com/dmitriikumancev/rusprofile-wrapper/blob/main/README.md Use grpcurl to test the gRPC endpoint for company information by INN. Demonstrates calls that return 'not found' and a successful '200' response. ```shell # Returns 'not found' grpcurl -plaintext -d '{"INN": "123"}' localhost:8888 rusprofile.v1.CompanyFinder/ByINN # Returns '200' grpcurl -plaintext -d '{"INN": "5003028028"}' localhost:8888 rusprofile.v1.CompanyFinder/ByINN ``` -------------------------------- ### HTTP/JSON Gateway Lookup by INN Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Shows how to perform company lookups via the HTTP gateway using `curl`. Expected responses include a JSON object on success (HTTP 200) or a JSON error body with HTTP 404 on failure. ```shell # Successful lookup curl http://localhost:8080/v1/company/5902879646 # Expected response (HTTP 200): # { # "INN": "5902879646", # "KPP": "590201001", # "name": "ООО \"Иксолла\"", # "CEO": "Чемоданова Валентина Игоревна" # } # Failed lookup curl -i http://localhost:8080/v1/company/123 # Expected response (HTTP 404): # HTTP/1.1 404 Not Found # { # "code": 5, # "message": "no company with provided INN", # "details": [] # } # Fetch the Swagger spec curl http://localhost:8080/swagger.json ``` -------------------------------- ### CompanyFinder.ByINN - gRPC RPC Method Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt The `ByINN` RPC method is the primary way to query company information using its INN. It accepts an INN string and returns a `Company` message containing INN, KPP, name, and CEO. A `NOT_FOUND` gRPC status is returned if no company matches the provided INN. ```APIDOC ## CompanyFinder.ByINN ### Description Accepts an INN string, queries rusprofile.ru, and returns the full `Company` message containing INN, KPP, company name, and CEO name. Returns a `NOT_FOUND` gRPC status code if no company matches the given INN. ### Method gRPC ### Endpoint `CompanyFinder.ByINN` ### Parameters #### Request Body - **INN** (string) - Required - The taxpayer identification number of the company. ### Request Example ```proto message INN { string INN = 1; } ``` ```json { "INN": "5902879646" } ``` ### Response #### Success Response - **Company** (object) - Contains company details. - **INN** (string) - The taxpayer identification number. - **KPP** (string) - The reason code for registration. - **name** (string) - The full company name. - **CEO** (string) - The name of the CEO. #### Response Example ```json { "INN": "5902879646", "KPP": "590201001", "name": "ООО \"Иксолла\"", "CEO": "Чемоданова Валентина Игоревна" } ``` #### Error Response - **Code**: `NotFound` - **Message**: `no company with provided INN` ``` -------------------------------- ### Rusprofile gRPC CompanyFinder.ByINN Method Definition Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Defines the gRPC service and messages for the CompanyFinder.ByINN RPC. This method accepts an INN and returns Company details or a NOT_FOUND status. ```proto // Proto definition service CompanyFinder { rpc ByINN(INN) returns (Company) { option (google.api.http) = { get: "/v1/company/{INN}" }; } } message INN { string INN = 1; } message Company { string INN = 1; string KPP = 2; string name = 3; string CEO = 4; } ``` -------------------------------- ### OAuth2 Redirect Logic Source: https://github.com/dmitriikumancev/rusprofile-wrapper/blob/main/static/web/oauth2-redirect.html This script processes the redirect from an OAuth2 provider. It extracts parameters from the URL, validates the state, and sends the authorization code or token back to the opener window. It also handles potential errors during the authorization process. ```javascript 'use strict'; function run () { var oauth2 = window.opener.swaggerUIRedirectOauth2; var sentState = oauth2.state; var redirectUrl = oauth2.redirectUrl; var isValid, qp, arr; if (/code|token|error/.test(window.location.hash)) { qp = window.location.hash.substring(1); } else { qp = location.search.substring(1); } arr = qp.split("&"); arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"'; }); qp = qp ? JSON.parse('{' + arr.join() + '}', function (key, value) { return key === "" ? value : decodeURIComponent(value); } ) : {}; isValid = qp.state === sentState; if (( oauth2.auth.schema.get("flow") === "accessCode" || oauth2.auth.schema.get("flow") === "authorizationCode" || oauth2.auth.schema.get("flow") === "authorization_code" ) && !oauth2.auth.code) { if (!isValid) { oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "warning", message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server" }); } if (qp.code) { delete oauth2.state; oauth2.auth.code = qp.code; oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); } else { let oauthErrorMsg; if (qp.error) { oauthErrorMsg = "["+qp.error+"]: " + (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + (qp.error_uri ? "More info: "+qp.error_uri : ""); } oauth2.errCb({ authId: oauth2.auth.name, source: "auth", level: "error", message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server" }); } } else { oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl}); } window.close(); } window.addEventListener('DOMContentLoaded', function () { run(); }); ``` -------------------------------- ### Internal rusprofile.ru Search Scraper Logic Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Details the internal mechanism for scraping rusprofile.ru. It queries the AJAX search endpoint, unmarshals JSON, and handles cases where no exact INN match is found by returning a gRPC NOT_FOUND status error. ```go // Internal call chain triggered by ByINN: // 1. fetchGeneralInfo → hits https://www.rusprofile.ru/ajax.php?query={INN}&action=search // Returns JSON: {"ul": [{"inn": "5902879646", "raw_name": "...", "ceo_name": "...", "url": "/..."}]} // 2. fetchKPP → hits https://www.rusprofile.ru/id/... and scrapes #clip_kpp element // Example of the underlying HTTP request constructed internally: // GET https://www.rusprofile.ru/ajax.php?query=5902879646&action=search // // Response JSON shape: // { // "ul": [ // { // "inn": "5902879646", // "raw_name": "ООО \"Иксолла\"", // "ceo_name": "Чемоданова Валентина Игоревна", // "url": "/id/1234567" // } // ] // } // // INN values in the response may be prefixed with "!" or "~"; these are trimmed: // strings.Trim(elem.INN, "!~") // // If no item with a matching INN is found → gRPC codes.NotFound is returned. // If the HTTP request or JSON parsing fails → gRPC codes.Internal is returned. ``` -------------------------------- ### fetchGeneralInfo Internal Scraper Source: https://context7.com/dmitriikumancev/rusprofile-wrapper/llms.txt Details the internal `fetchGeneralInfo` function which scrapes rusprofile.ru for company data using an INN. ```APIDOC ## fetchGeneralInfo ### Description This internal function queries the rusprofile.ru AJAX search endpoint to scrape company information based on the provided INN. It unmarshals the JSON response and returns the matching company details. If an exact INN match is not found, it returns a gRPC `NOT_FOUND` status error. ### Method HTTP GET request to `https://www.rusprofile.ru/ajax.php` ### Endpoint `https://www.rusprofile.ru/ajax.php?query={INN}&action=search` ### Parameters #### Query Parameters - **query** (string) - Required - The INN of the company to search for. - **action** (string) - Required - Must be set to `search`. ### Request Example `GET https://www.rusprofile.ru/ajax.php?query=5902879646&action=search` ### Response #### Success Response (200) Returns JSON with a list of companies matching the query. The relevant fields for each company include: - **inn** (string) - The INN of the company (may be prefixed with '!' or '~', which are trimmed). - **raw_name** (string) - The raw name of the company. - **ceo_name** (string) - The name of the company's CEO. - **url** (string) - The URL to the company's profile page. #### Response Example ```json { "ul": [ { "inn": "5902879646", "raw_name": "ООО \"Иксолла\"", "ceo_name": "Чемоданова Валентина Игоревна", "url": "/id/1234567" } ] } ``` #### Error Response - **gRPC codes.NotFound**: Returned if no item with a matching INN is found in the response. - **gRPC codes.Internal**: Returned if the HTTP request or JSON parsing fails. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.