Jump to content

araujoarthur

Members
  • Content Count

    3
  • Joined

  • Last visited

Community Reputation

0 Neutral

About araujoarthur

  • Birthday 11/11/1999

Technical Information

  • Delphi-Version
    Delphi 12 Athens

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hello y'all! I'm developing a Shopee Wrapper in Delphi and ran into a pitfall. I also ran into a similar problem that was answered on StackOverflow. I need to handle two kinds of asynchronous behavior that are needed for the main program (and the VCL visual part), but I don't know WHAT I should do for this. My issue starts with the following constructor noted in the code block (1). After the Authorize; call, any instruction dependent on Authorization Code falls into Undefined Behavior because there's no guarantee I have a code. I would need to wait for Authorize to return before following on. My issue arises from the fact that Authorize creates an object and starts a routine that is Asynchronous, a HTTP listener (as noted in code block) (2). The AuthorizationRequest procedure is implemented as shown and so does FieldsReadyHandler (which is the subject of my older question) in the current version.(3, 4). I was told to post here to get a better guidance on how to learn this subject and overcome this obstacle. I would like to answer the question "Why is there a server that is created then destroyed after a simple request". That was a design choice I made (maybe a poor one, I'm open to change this) for the URI. I needed it to be local so I came with the idea of opening a simple http server, waiting for the Authorization redirect, catching the code and shop_id then freeing it. This process is necessary at least once every 365 days. Usually it's a matter of HOW to do that, but honestly at this point I'm thinking that I overcomplicated it and don't even know WHAT I should do to overcome this. Anyways, if I were to rewrite I can see my self falling in the same spot where my subsequent tasks depends on the async task to finish. I also tried to add an event to inform the Context that it already obtained the code but (my shot is) it raises access violation because of the way the object is released. Sorry I can't synthesize a TL;DR for this one, but if I had to index my questions the output would be: What is the best approach to this type of problem and how is it handled in pascal? In JS, for example, I would chain infinite .then() until the routine doesn't need the async part anymore. I also feel it is going to become a frequent pain if I don't learn to handle it now as requests are asynchronous. Thanks in advance. {1. The constructor } constructor TShopeeContext.Create(AMode, AAPIKey, APartnerID: string); begin if (AMode <> TEST_SHOPEE) and (AMode <> PRODUCTION_SHOPEE_BR) then raise Exception.Create('Mode Invalid for Context'); FHost := AMode; FAPI_Key := AAPIKey; FPartnerID := APartnerID; UpdateInternalConfigFields; if FRefreshToken = '' then FHasRefreshToken := False else FHasRefreshToken := True; // Checks if the authorization has been granted and is younger than 365 days. if (not FAuthorizationGranted) or ((Now - FAuthorizationDate) > 365) then begin Authorize; end; end; { 2. Authorize Procedure } procedure TShopeeContext.Authorize; var Authorizator: TShopeeAuthorizator; begin // Request Authorization; Authorizator := TShopeeAuthorizator.Create(FHost, FAPI_Key, FPartnerID, 8342); try Authorizator.AuthorizationRequest; finally Authorizator.Free; end; end; { 3. AuthorizationRequest implementation } procedure TShopeeAuthorizator.AuthorizationRequest; begin // Obtem a assinatura da chamada FSignature := GetPublicSignString(API_PATH_AUTHORIZATION, FTimestamp); // Constroi os parametros FRequestParameters.AddItem('partner_id', FPartnerID); FRequestParameters.AddItem('timestamp', FTimeStamp); FRequestParameters.AddItem('sign', FSignature); FRequestParameters.AddItem('redirect', REDIRECT_URL_WS+':'+IntToStr(FPort)); ShellExecute(0, 'open', PChar(GenerateRequestURL(API_PATH_AUTHORIZATION, FRequestParameters)), nil, nil, SW_SHOWNORMAL); FCatcherServer := TCatcherServer.Create(); FCatcherServer.OnFieldsReady := FieldsReadyHandler; FCatcherServer.Listen(FPort); end; {4. FieldsReadyHandler implementation} procedure TShopeeAuthorizator.FieldsReadyHandler(Sender: TObject; Code, AuthorizatedID: string); begin // Handle Code, Auth Type and AuthorizatedID. FConfigurator := TConfiguratorFile.Create; try FConfigurator.SaveAuthorizationInfo(Code, AuthorizatedID, (Sender as TCatcherServer).AuthorizationType); FSuccess := True; finally FConfigurator.Free; end; TThread.Queue(nil, procedure begin Sender.Free; end); end;
  2. Lmao I wasn't expecting an answer from you. So based on your answer I can't (and don't need) to load individual functions? I assume MainModule is in the tree of PyEngine, how would this work in case of a package with multiple modules? Thanks for your answer.
  3. I've been looking around for some way to call python functions (using Python4Delphi) within my delphi code without direct need for TPythonEngine.ExecStrings execution. My base idea is to load a module, for instance, example.py looking like: def DoExample(pStr: str) -> str: pStr = "Example: " + pStr return pStr And call it like (disclaimer: example of behavior I'd like to have, not actual P4D behavior): MyPythonEngine := TPythonEngine.Create(nil); {necessary version, flags and LoadDll} MyPythonModule := TPythonModule.Create(nil); {necessary configs again} MyImportedFunction := {Load the DoExample somehow and store it in this variable} ResultOfMyImportedFunction := MyImportedFunction("This is an example"); {This should be Example: This is an example} I could also achieve my goal by adapting the example.py: import sys def DoExample(pStr: str) -> str: pStr = "Example: " + pStr return pStr DoExample(sys.argv[1]) And call it like I would in cli, still need to get its result. I've intensively read the Demos and didn't find a reasonable answer to my problem. Also no documentation for further reading (or atleast I couldn't find it). I don't know if this approach is possible due to lack of documentation so I'm looking for comments from people more familiar with the library. Question was originally posted in StackOverflow. tl;dr I'd like load a python script, take one of its defined functions, call it within delphi and retrieve its result into a varaible.|
×